@keep-network/tbtc-v2 1.3.0-dev.4 → 1.3.0-dev.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/artifacts/BLS.json +1 -1
  2. package/artifacts/Bank.json +3 -3
  3. package/artifacts/BeaconAuthorization.json +1 -1
  4. package/artifacts/BeaconDkg.json +1 -1
  5. package/artifacts/BeaconDkgValidator.json +1 -1
  6. package/artifacts/BeaconInactivity.json +1 -1
  7. package/artifacts/BeaconSortitionPool.json +3 -3
  8. package/artifacts/Bridge.json +5 -5
  9. package/artifacts/BridgeGovernance.json +2 -2
  10. package/artifacts/BridgeGovernanceParameters.json +2 -2
  11. package/artifacts/Deposit.json +2 -2
  12. package/artifacts/DepositSweep.json +2 -2
  13. package/artifacts/DonationVault.json +3 -3
  14. package/artifacts/EcdsaDkgValidator.json +1 -1
  15. package/artifacts/EcdsaInactivity.json +1 -1
  16. package/artifacts/EcdsaSortitionPool.json +3 -3
  17. package/artifacts/Fraud.json +2 -2
  18. package/artifacts/KeepRegistry.json +1 -1
  19. package/artifacts/KeepStake.json +2 -2
  20. package/artifacts/KeepToken.json +2 -2
  21. package/artifacts/KeepTokenStaking.json +1 -1
  22. package/artifacts/LightRelay.json +3 -3
  23. package/artifacts/LightRelayMaintainerProxy.json +479 -0
  24. package/artifacts/MaintainerProxy.json +3 -3
  25. package/artifacts/MovingFunds.json +2 -2
  26. package/artifacts/NuCypherStakingEscrow.json +1 -1
  27. package/artifacts/NuCypherToken.json +2 -2
  28. package/artifacts/RandomBeacon.json +2 -2
  29. package/artifacts/RandomBeaconChaosnet.json +2 -2
  30. package/artifacts/RandomBeaconGovernance.json +2 -2
  31. package/artifacts/Redemption.json +2 -2
  32. package/artifacts/ReimbursementPool.json +2 -2
  33. package/artifacts/T.json +2 -2
  34. package/artifacts/TBTC.json +3 -3
  35. package/artifacts/TBTCToken.json +3 -3
  36. package/artifacts/TBTCVault.json +23 -23
  37. package/artifacts/TokenStaking.json +1 -1
  38. package/artifacts/TokenholderGovernor.json +9 -9
  39. package/artifacts/TokenholderTimelock.json +8 -8
  40. package/artifacts/VendingMachine.json +3 -3
  41. package/artifacts/VendingMachineKeep.json +1 -1
  42. package/artifacts/VendingMachineNuCypher.json +1 -1
  43. package/artifacts/VendingMachineV2.json +3 -3
  44. package/artifacts/VendingMachineV3.json +3 -3
  45. package/artifacts/WalletCoordinator.json +5 -5
  46. package/artifacts/WalletRegistry.json +5 -5
  47. package/artifacts/WalletRegistryGovernance.json +2 -2
  48. package/artifacts/Wallets.json +2 -2
  49. package/artifacts/solcInputs/{609b7e5bc658a3c9d056ae5f7bac2b7c.json → 08bd3c90d7f376263925b4f52b0adff9.json} +3 -0
  50. package/build/contracts/GovernanceUtils.sol/GovernanceUtils.dbg.json +1 -1
  51. package/build/contracts/bank/Bank.sol/Bank.dbg.json +1 -1
  52. package/build/contracts/bank/IReceiveBalanceApproval.sol/IReceiveBalanceApproval.dbg.json +1 -1
  53. package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.dbg.json +1 -1
  54. package/build/contracts/bridge/Bridge.sol/Bridge.dbg.json +1 -1
  55. package/build/contracts/bridge/BridgeGovernanceParameters.sol/BridgeGovernanceParameters.dbg.json +1 -1
  56. package/build/contracts/bridge/BridgeState.sol/BridgeState.dbg.json +1 -1
  57. package/build/contracts/bridge/Deposit.sol/Deposit.dbg.json +1 -1
  58. package/build/contracts/bridge/DepositSweep.sol/DepositSweep.dbg.json +1 -1
  59. package/build/contracts/bridge/EcdsaLib.sol/EcdsaLib.dbg.json +1 -1
  60. package/build/contracts/bridge/Fraud.sol/Fraud.dbg.json +1 -1
  61. package/build/contracts/bridge/Heartbeat.sol/Heartbeat.dbg.json +1 -1
  62. package/build/contracts/bridge/IRelay.sol/IRelay.dbg.json +1 -1
  63. package/build/contracts/bridge/MovingFunds.sol/MovingFunds.dbg.json +1 -1
  64. package/build/contracts/bridge/Redemption.sol/OutboundTx.dbg.json +1 -1
  65. package/build/contracts/bridge/Redemption.sol/Redemption.dbg.json +1 -1
  66. package/build/contracts/bridge/VendingMachine.sol/VendingMachine.dbg.json +1 -1
  67. package/build/contracts/bridge/VendingMachineV2.sol/VendingMachineV2.dbg.json +1 -1
  68. package/build/contracts/bridge/VendingMachineV3.sol/VendingMachineV3.dbg.json +1 -1
  69. package/build/contracts/bridge/WalletCoordinator.sol/WalletCoordinator.dbg.json +1 -1
  70. package/build/contracts/bridge/Wallets.sol/Wallets.dbg.json +1 -1
  71. package/build/contracts/l2/L2TBTC.sol/L2TBTC.dbg.json +1 -1
  72. package/build/contracts/l2/L2WormholeGateway.sol/IWormholeTokenBridge.dbg.json +1 -1
  73. package/build/contracts/l2/L2WormholeGateway.sol/L2WormholeGateway.dbg.json +1 -1
  74. package/build/contracts/maintainer/MaintainerProxy.sol/MaintainerProxy.dbg.json +1 -1
  75. package/build/contracts/relay/LightRelay.sol/ILightRelay.dbg.json +1 -1
  76. package/build/contracts/relay/LightRelay.sol/LightRelay.dbg.json +1 -1
  77. package/build/contracts/relay/LightRelay.sol/RelayUtils.dbg.json +1 -1
  78. package/build/contracts/relay/LightRelayMaintainerProxy.sol/LightRelayMaintainerProxy.dbg.json +4 -0
  79. package/build/contracts/relay/LightRelayMaintainerProxy.sol/LightRelayMaintainerProxy.json +280 -0
  80. package/build/contracts/token/TBTC.sol/TBTC.dbg.json +1 -1
  81. package/build/contracts/vault/DonationVault.sol/DonationVault.dbg.json +1 -1
  82. package/build/contracts/vault/IVault.sol/IVault.dbg.json +1 -1
  83. package/build/contracts/vault/TBTCOptimisticMinting.sol/TBTCOptimisticMinting.dbg.json +1 -1
  84. package/build/contracts/vault/TBTCVault.sol/TBTCVault.dbg.json +1 -1
  85. package/contracts/relay/LightRelayMaintainerProxy.sol +147 -0
  86. package/deploy/36_deploy_light_relay_maintainer_proxy.ts +35 -0
  87. package/deploy/37_transfer_light_relay_maintainer_proxy_ownership.ts +19 -0
  88. package/deploy/38_authorize_light_relay_maintainer_proxy_in_reimbursement_pool.ts +31 -0
  89. package/deploy/39_authorize_light_relay_maintainer_proxy_in_light_relay.ts +24 -0
  90. package/deploy/94_transfer_relay_ownership.ts +19 -0
  91. package/export/artifacts/@keep-network/bitcoin-spv-sol/contracts/BTCUtils.sol/BTCUtils.json +20 -20
  92. package/export/artifacts/@keep-network/ecdsa/contracts/EcdsaDkgValidator.sol/EcdsaDkgValidator.json +1986 -1986
  93. package/export/artifacts/@keep-network/ecdsa/contracts/libraries/EcdsaDkg.sol/EcdsaDkg.json +20 -20
  94. package/export/artifacts/@keep-network/ecdsa/contracts/libraries/EcdsaInactivity.sol/EcdsaInactivity.json +1836 -1836
  95. package/export/artifacts/@keep-network/random-beacon/contracts/ReimbursementPool.sol/ReimbursementPool.json +545 -545
  96. package/export/artifacts/@keep-network/sortition-pools/contracts/Chaosnet.sol/Chaosnet.json +506 -506
  97. package/export/artifacts/@keep-network/sortition-pools/contracts/Rewards.sol/Rewards.json +23 -23
  98. package/export/artifacts/@keep-network/sortition-pools/contracts/SortitionPool.sol/SortitionPool.json +2456 -2456
  99. package/export/artifacts/@keep-network/sortition-pools/contracts/SortitionTree.sol/SortitionTree.json +465 -465
  100. package/export/artifacts/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol/ERC1967Proxy.json +568 -568
  101. package/export/artifacts/@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol/ProxyAdmin.json +603 -603
  102. package/export/artifacts/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json +1001 -1001
  103. package/export/artifacts/@openzeppelin/contracts/token/ERC721/ERC721.sol/ERC721.json +1877 -1877
  104. package/export/artifacts/@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol/ERC20Upgradeable.json +654 -654
  105. package/export/artifacts/@thesis/solidity-contracts/contracts/token/ERC20WithPermit.sol/ERC20WithPermit.json +2534 -2534
  106. package/export/artifacts/@thesis/solidity-contracts/contracts/token/MisfundRecovery.sol/MisfundRecovery.json +736 -736
  107. package/export/artifacts/contracts/bank/Bank.sol/Bank.json +1872 -1872
  108. package/export/artifacts/contracts/bridge/Bridge.sol/Bridge.json +7061 -7061
  109. package/export/artifacts/contracts/bridge/VendingMachine.sol/VendingMachine.json +1257 -1257
  110. package/export/artifacts/contracts/bridge/VendingMachineV2.sol/VendingMachineV2.json +972 -972
  111. package/export/artifacts/contracts/bridge/VendingMachineV3.sol/VendingMachineV3.json +1122 -1122
  112. package/export/artifacts/contracts/bridge/WalletCoordinator.sol/WalletCoordinator.json +4172 -4172
  113. package/export/artifacts/contracts/l2/L2TBTC.sol/L2TBTC.json +2961 -2961
  114. package/export/artifacts/contracts/l2/L2WormholeGateway.sol/L2WormholeGateway.json +2424 -2424
  115. package/export/artifacts/contracts/maintainer/MaintainerProxy.sol/MaintainerProxy.json +2305 -2305
  116. package/export/artifacts/contracts/relay/LightRelay.sol/LightRelay.json +1864 -1864
  117. package/export/artifacts/contracts/relay/LightRelayMaintainerProxy.sol/LightRelayMaintainerProxy.json +6348 -0
  118. package/export/artifacts/contracts/test/BankStub.sol/BankStub.json +1874 -1874
  119. package/export/artifacts/contracts/test/BridgeStub.sol/BridgeStub.json +8094 -8094
  120. package/export/artifacts/contracts/test/GoerliLightRelay.sol/GoerliLightRelay.json +1869 -1869
  121. package/export/artifacts/contracts/test/HeartbeatStub.sol/HeartbeatStub.json +130 -130
  122. package/export/artifacts/contracts/test/LightRelayStub.sol/LightRelayStub.json +1990 -1990
  123. package/export/artifacts/contracts/test/ReceiveApprovalStub.sol/ReceiveApprovalStub.json +354 -354
  124. package/export/artifacts/contracts/test/SystemTestRelay.sol/SystemTestRelay.json +568 -568
  125. package/export/artifacts/contracts/test/TestERC20.sol/TestERC20.json +2291 -2291
  126. package/export/artifacts/contracts/test/TestERC721.sol/TestERC721.json +1698 -1698
  127. package/export/artifacts/contracts/test/TestEcdsaLib.sol/TestEcdsaLib.json +189 -189
  128. package/export/artifacts/contracts/test/WormholeBridgeStub.sol/WormholeBridgeStub.json +1443 -1443
  129. package/export/artifacts/contracts/token/TBTC.sol/TBTC.json +2847 -2847
  130. package/export/artifacts/contracts/vault/DonationVault.sol/DonationVault.json +858 -858
  131. package/export/artifacts/contracts/vault/TBTCVault.sol/TBTCVault.json +3476 -3476
  132. package/export/deploy/36_deploy_light_relay_maintainer_proxy.js +86 -0
  133. package/export/deploy/37_transfer_light_relay_maintainer_proxy_ownership.js +60 -0
  134. package/export/deploy/38_authorize_light_relay_maintainer_proxy_in_reimbursement_pool.js +70 -0
  135. package/export/deploy/39_authorize_light_relay_maintainer_proxy_in_light_relay.js +63 -0
  136. package/export/deploy/94_transfer_relay_ownership.js +64 -0
  137. package/export/typechain/LightRelayMaintainerProxy.js +2 -0
  138. package/export/typechain/factories/LightRelayMaintainerProxy__factory.js +359 -0
  139. package/export/typechain/index.js +3 -1
  140. package/package.json +1 -1
@@ -325,6 +325,9 @@
325
325
  "contracts/relay/LightRelay.sol": {
326
326
  "content": "// SPDX-License-Identifier: GPL-3.0-only\n\n// ██████████████ ▐████▌ ██████████████\n// ██████████████ ▐████▌ ██████████████\n// ▐████▌ ▐████▌\n// ▐████▌ ▐████▌\n// ██████████████ ▐████▌ ██████████████\n// ██████████████ ▐████▌ ██████████████\n// ▐████▌ ▐████▌\n// ▐████▌ ▐████▌\n// ▐████▌ ▐████▌\n// ▐████▌ ▐████▌\n// ▐████▌ ▐████▌\n// ▐████▌ ▐████▌\n\npragma solidity 0.8.17;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport {BytesLib} from \"@keep-network/bitcoin-spv-sol/contracts/BytesLib.sol\";\nimport {BTCUtils} from \"@keep-network/bitcoin-spv-sol/contracts/BTCUtils.sol\";\nimport {ValidateSPV} from \"@keep-network/bitcoin-spv-sol/contracts/ValidateSPV.sol\";\n\nimport \"../bridge/IRelay.sol\";\n\nstruct Epoch {\n uint32 timestamp;\n // By definition, bitcoin targets have at least 32 leading zero bits.\n // Thus we can only store the bits that aren't guaranteed to be 0.\n uint224 target;\n}\n\ninterface ILightRelay is IRelay {\n event Genesis(uint256 blockHeight);\n event Retarget(uint256 oldDifficulty, uint256 newDifficulty);\n event ProofLengthChanged(uint256 newLength);\n event AuthorizationRequirementChanged(bool newStatus);\n event SubmitterAuthorized(address submitter);\n event SubmitterDeauthorized(address submitter);\n\n function retarget(bytes memory headers) external;\n\n function validateChain(bytes memory headers)\n external\n view\n returns (uint256 startingHeaderTimestamp, uint256 headerCount);\n\n function getBlockDifficulty(uint256 blockNumber)\n external\n view\n returns (uint256);\n\n function getEpochDifficulty(uint256 epochNumber)\n external\n view\n returns (uint256);\n\n function getRelayRange()\n external\n view\n returns (uint256 relayGenesis, uint256 currentEpochEnd);\n}\n\nlibrary RelayUtils {\n using BytesLib for bytes;\n\n /// @notice Extract the timestamp of the header at the given position.\n /// @param headers Byte array containing the header of interest.\n /// @param at The start of the header in the array.\n /// @return The timestamp of the header.\n /// @dev Assumes that the specified position contains a valid header.\n /// Performs no validation whatsoever.\n function extractTimestampAt(bytes memory headers, uint256 at)\n internal\n pure\n returns (uint32)\n {\n return BTCUtils.reverseUint32(uint32(headers.slice4(68 + at)));\n }\n}\n\n/// @dev THE RELAY MUST NOT BE USED BEFORE GENESIS AND AT LEAST ONE RETARGET.\ncontract LightRelay is Ownable, ILightRelay {\n using BytesLib for bytes;\n using BTCUtils for bytes;\n using ValidateSPV for bytes;\n using RelayUtils for bytes;\n\n bool public ready;\n // Whether the relay requires the address submitting a retarget to be\n // authorised in advance by governance.\n bool public authorizationRequired;\n // Number of blocks required for each side of a retarget proof:\n // a retarget must provide `proofLength` blocks before the retarget\n // and `proofLength` blocks after it.\n // Governable\n // Should be set to a fairly high number (e.g. 20-50) in production.\n uint64 public proofLength;\n // The number of the first epoch recorded by the relay.\n // This should equal the height of the block starting the genesis epoch,\n // divided by 2016, but this is not enforced as the relay has no\n // information about block numbers.\n uint64 public genesisEpoch;\n // The number of the latest epoch whose difficulty is proven to the relay.\n // If the genesis epoch's number is set correctly, and retargets along the\n // way have been legitimate, this equals the height of the block starting\n // the most recent epoch, divided by 2016.\n uint64 public currentEpoch;\n\n uint256 internal currentEpochDifficulty;\n uint256 internal prevEpochDifficulty;\n\n // Each epoch from genesis to the current one, keyed by their numbers.\n mapping(uint256 => Epoch) internal epochs;\n\n mapping(address => bool) public isAuthorized;\n\n modifier relayActive() {\n require(ready, \"Relay is not ready for use\");\n _;\n }\n\n /// @notice Establish a starting point for the relay by providing the\n /// target, timestamp and blockheight of the first block of the relay\n /// genesis epoch.\n /// @param genesisHeader The first block header of the genesis epoch.\n /// @param genesisHeight The block number of the first block of the epoch.\n /// @param genesisProofLength The number of blocks required to accept a\n /// proof.\n /// @dev If the relay is used by querying the current and previous epoch\n /// difficulty, at least one retarget needs to be provided after genesis;\n /// otherwise the prevEpochDifficulty will be uninitialised and zero.\n function genesis(\n bytes calldata genesisHeader,\n uint256 genesisHeight,\n uint64 genesisProofLength\n ) external onlyOwner {\n require(!ready, \"Genesis already performed\");\n\n require(genesisHeader.length == 80, \"Invalid genesis header length\");\n\n require(\n genesisHeight % 2016 == 0,\n \"Invalid height of relay genesis block\"\n );\n\n require(genesisProofLength < 2016, \"Proof length excessive\");\n require(genesisProofLength > 0, \"Proof length may not be zero\");\n\n genesisEpoch = uint64(genesisHeight / 2016);\n currentEpoch = genesisEpoch;\n uint256 genesisTarget = genesisHeader.extractTarget();\n uint256 genesisTimestamp = genesisHeader.extractTimestamp();\n epochs[genesisEpoch] = Epoch(\n uint32(genesisTimestamp),\n uint224(genesisTarget)\n );\n proofLength = genesisProofLength;\n currentEpochDifficulty = BTCUtils.calculateDifficulty(genesisTarget);\n ready = true;\n\n emit Genesis(genesisHeight);\n }\n\n /// @notice Set the number of blocks required to accept a header chain.\n /// @param newLength The required number of blocks. Must be less than 2016.\n /// @dev For production, a high number (e.g. 20-50) is recommended.\n /// Small numbers are accepted but should only be used for testing.\n function setProofLength(uint64 newLength) external relayActive onlyOwner {\n require(newLength < 2016, \"Proof length excessive\");\n require(newLength > 0, \"Proof length may not be zero\");\n require(newLength != proofLength, \"Proof length unchanged\");\n proofLength = newLength;\n emit ProofLengthChanged(newLength);\n }\n\n /// @notice Set whether the relay requires retarget submitters to be\n /// pre-authorised by governance.\n /// @param status True if authorisation is to be required, false if not.\n function setAuthorizationStatus(bool status) external onlyOwner {\n authorizationRequired = status;\n emit AuthorizationRequirementChanged(status);\n }\n\n /// @notice Authorise the given address to submit retarget proofs.\n /// @param submitter The address to be authorised.\n function authorize(address submitter) external onlyOwner {\n isAuthorized[submitter] = true;\n emit SubmitterAuthorized(submitter);\n }\n\n /// @notice Rescind the authorisation of the submitter to retarget.\n /// @param submitter The address to be deauthorised.\n function deauthorize(address submitter) external onlyOwner {\n isAuthorized[submitter] = false;\n emit SubmitterDeauthorized(submitter);\n }\n\n /// @notice Add a new epoch to the relay by providing a proof\n /// of the difficulty before and after the retarget.\n /// @param headers A chain of headers including the last X blocks before\n /// the retarget, followed by the first X blocks after the retarget,\n /// where X equals the current proof length.\n /// @dev Checks that the first X blocks are valid in the most recent epoch,\n /// that the difficulty of the new epoch is calculated correctly according\n /// to the block timestamps, and that the next X blocks would be valid in\n /// the new epoch.\n /// We have no information of block heights, so we cannot enforce that\n /// retargets only happen every 2016 blocks; instead, we assume that this\n /// is the case if a valid proof of work is provided.\n /// It is possible to cheat the relay by providing X blocks from earlier in\n /// the most recent epoch, and then mining X new blocks after them.\n /// However, each of these malicious blocks would have to be mined to a\n /// higher difficulty than the legitimate ones.\n /// Alternatively, if the retarget has not been performed yet, one could\n /// first mine X blocks in the old difficulty with timestamps set far in\n /// the future, and then another X blocks at a greatly reduced difficulty.\n /// In either case, cheating the realy requires more work than mining X\n /// legitimate blocks.\n /// Only the most recent epoch is vulnerable to these attacks; once a\n /// retarget has been proven to the relay, the epoch is immutable even if a\n /// contradictory proof were to be presented later.\n function retarget(bytes memory headers) external relayActive {\n if (authorizationRequired) {\n require(isAuthorized[msg.sender], \"Submitter unauthorized\");\n }\n\n require(\n // Require proofLength headers on both sides of the retarget\n headers.length == (proofLength * 2 * 80),\n \"Invalid header length\"\n );\n\n Epoch storage latest = epochs[currentEpoch];\n\n uint256 oldTarget = latest.target;\n\n bytes32 previousHeaderDigest = bytes32(0);\n\n // Validate old chain\n for (uint256 i = 0; i < proofLength; i++) {\n (\n bytes32 currentDigest,\n uint256 currentHeaderTarget\n ) = validateHeader(headers, i * 80, previousHeaderDigest);\n\n require(\n currentHeaderTarget == oldTarget,\n \"Invalid target in pre-retarget headers\"\n );\n\n previousHeaderDigest = currentDigest;\n }\n\n // get timestamp of retarget block\n uint256 epochEndTimestamp = headers.extractTimestampAt(\n (proofLength - 1) * 80\n );\n\n // An attacker could produce blocks with timestamps in the future,\n // in an attempt to reduce the difficulty after the retarget\n // to make mining the second part of the retarget proof easier.\n // In particular, the attacker could reuse all but one block\n // from the legitimate chain, and only mine the last block.\n // To hinder this, require that the epoch end timestamp does not\n // exceed the ethereum timestamp.\n // NOTE: both are unix seconds, so this comparison should be valid.\n require(\n /* solhint-disable-next-line not-rely-on-time */\n epochEndTimestamp < block.timestamp,\n \"Epoch cannot end in the future\"\n );\n\n // Expected target is the full-length target\n uint256 expectedTarget = BTCUtils.retargetAlgorithm(\n oldTarget,\n latest.timestamp,\n epochEndTimestamp\n );\n\n // Mined target is the header-encoded target\n uint256 minedTarget = 0;\n\n uint256 epochStartTimestamp = headers.extractTimestampAt(\n proofLength * 80\n );\n\n // validate new chain\n for (uint256 j = proofLength; j < proofLength * 2; j++) {\n (\n bytes32 _currentDigest,\n uint256 _currentHeaderTarget\n ) = validateHeader(headers, j * 80, previousHeaderDigest);\n\n if (minedTarget == 0) {\n // The new target has not been set, so check its correctness\n minedTarget = _currentHeaderTarget;\n require(\n // Although the target is a 256-bit number, there are only 32 bits of\n // space in the Bitcoin header. Because of that, the version stored in\n // the header is a less-precise representation of the actual target\n // using base-256 version of scientific notation.\n //\n // The 256-bit unsigned integer returned from BTCUtils.retargetAlgorithm\n // is the precise target value.\n // The 256-bit unsigned integer returned from validateHeader is the less\n // precise target value because it was read from 32 bits of space of\n // Bitcoin block header.\n //\n // We can't compare the precise and less precise representations together\n // so we first mask them to obtain the less precise version:\n // (full & truncated) == truncated\n _currentHeaderTarget ==\n (expectedTarget & _currentHeaderTarget),\n \"Invalid target in new epoch\"\n );\n } else {\n // The new target has been set, so remaining targets should match.\n require(\n _currentHeaderTarget == minedTarget,\n \"Unexpected target change after retarget\"\n );\n }\n\n previousHeaderDigest = _currentDigest;\n }\n\n currentEpoch = currentEpoch + 1;\n\n epochs[currentEpoch] = Epoch(\n uint32(epochStartTimestamp),\n uint224(minedTarget)\n );\n\n uint256 oldDifficulty = currentEpochDifficulty;\n uint256 newDifficulty = BTCUtils.calculateDifficulty(minedTarget);\n\n prevEpochDifficulty = oldDifficulty;\n currentEpochDifficulty = newDifficulty;\n\n emit Retarget(oldDifficulty, newDifficulty);\n }\n\n /// @notice Check whether a given chain of headers should be accepted as\n /// valid within the rules of the relay.\n /// If the validation fails, this function throws an exception.\n /// @param headers A chain of 2 to 2015 bitcoin headers.\n /// @return startingHeaderTimestamp The timestamp of the first header.\n /// @return headerCount The number of headers.\n /// @dev A chain of headers is accepted as valid if:\n /// - Its length is between 2 and 2015 headers.\n /// - Headers in the chain are sequential and refer to previous digests.\n /// - Each header is mined with the correct amount of work.\n /// - The difficulty in each header matches an epoch of the relay,\n /// as determined by the headers' timestamps. The headers must be between\n /// the genesis epoch and the latest proven epoch (inclusive).\n /// If the chain contains a retarget, it is accepted if the retarget has\n /// already been proven to the relay.\n /// If the chain contains blocks of an epoch that has not been proven to\n /// the relay (after a retarget within the header chain, or when the entire\n /// chain falls within an epoch that has not been proven yet), it will be\n /// rejected.\n /// One exception to this is when two subsequent epochs have exactly the\n /// same difficulty; headers from the latter epoch will be accepted if the\n /// previous epoch has been proven to the relay.\n /// This is because it is not possible to distinguish such headers from\n /// headers of the previous epoch.\n ///\n /// If the difficulty increases significantly between relay genesis and the\n /// present, creating fraudulent proofs for earlier epochs becomes easier.\n /// Users of the relay should check the timestamps of valid headers and\n /// only accept appropriately recent ones.\n function validateChain(bytes memory headers)\n external\n view\n returns (uint256 startingHeaderTimestamp, uint256 headerCount)\n {\n require(headers.length % 80 == 0, \"Invalid header length\");\n\n headerCount = headers.length / 80;\n\n require(\n headerCount > 1 && headerCount < 2016,\n \"Invalid number of headers\"\n );\n\n startingHeaderTimestamp = headers.extractTimestamp();\n\n // Short-circuit the first header's validation.\n // We validate the header here to get the target which is needed to\n // precisely identify the epoch.\n (\n bytes32 previousHeaderDigest,\n uint256 currentHeaderTarget\n ) = validateHeader(headers, 0, bytes32(0));\n\n Epoch memory nullEpoch = Epoch(0, 0);\n\n uint256 startingEpochNumber = currentEpoch;\n Epoch memory startingEpoch = epochs[startingEpochNumber];\n Epoch memory nextEpoch = nullEpoch;\n\n // Find the correct epoch for the given chain\n // Fastest with recent epochs, but able to handle anything after genesis\n //\n // The rules for bitcoin timestamps are:\n // - must be greater than the median of the last 11 blocks' timestamps\n // - must be less than the network-adjusted time +2 hours\n //\n // Because of this, the timestamp of a header may be smaller than the\n // starting time, or greater than the ending time of its epoch.\n // However, a valid timestamp is guaranteed to fall within the window\n // formed by the epochs immediately before and after its timestamp.\n // We can identify cases like these by comparing the targets.\n while (startingHeaderTimestamp < startingEpoch.timestamp) {\n startingEpochNumber -= 1;\n nextEpoch = startingEpoch;\n startingEpoch = epochs[startingEpochNumber];\n }\n\n // We have identified the centre of the window,\n // by reaching the most recent epoch whose starting timestamp\n // or reached before the genesis where epoch slots are empty.\n // Therefore check that the timestamp is nonzero.\n require(\n startingEpoch.timestamp > 0,\n \"Cannot validate chains before relay genesis\"\n );\n\n // The targets don't match. This could be because the block is invalid,\n // or it could be because of timestamp inaccuracy.\n // To cover the latter case, check adjacent epochs.\n if (currentHeaderTarget != startingEpoch.target) {\n // The target matches the next epoch.\n // This means we are right at the beginning of the next epoch,\n // and retargets during the chain should not be possible.\n if (currentHeaderTarget == nextEpoch.target) {\n startingEpoch = nextEpoch;\n nextEpoch = nullEpoch;\n }\n // The target doesn't match the next epoch.\n // Therefore the only valid epoch is the previous one.\n // Because the timestamp can't be more than 2 hours into the future\n // we must be right near the end of the epoch,\n // so a retarget is possible.\n else {\n startingEpochNumber -= 1;\n nextEpoch = startingEpoch;\n startingEpoch = epochs[startingEpochNumber];\n\n // We have failed to find a match,\n // therefore the target has to be invalid.\n require(\n currentHeaderTarget == startingEpoch.target,\n \"Invalid target in header chain\"\n );\n }\n }\n\n // We've found the correct epoch for the first header.\n // Validate the rest.\n for (uint256 i = 1; i < headerCount; i++) {\n bytes32 currentDigest;\n (currentDigest, currentHeaderTarget) = validateHeader(\n headers,\n i * 80,\n previousHeaderDigest\n );\n\n // If the header's target does not match the expected target,\n // check if a retarget is possible.\n //\n // If next epoch timestamp exists, a valid retarget is possible\n // (if next epoch timestamp doesn't exist, either a retarget has\n // already happened in this chain, the relay needs a retarget\n // before this chain can be validated, or a retarget is not allowed\n // because we know the headers are within a timestamp irregularity\n // of the previous retarget).\n //\n // In this case the target must match the next epoch's target,\n // and the header's timestamp must match the epoch's start.\n if (currentHeaderTarget != startingEpoch.target) {\n uint256 currentHeaderTimestamp = headers.extractTimestampAt(\n i * 80\n );\n\n require(\n nextEpoch.timestamp != 0 &&\n currentHeaderTarget == nextEpoch.target &&\n currentHeaderTimestamp == nextEpoch.timestamp,\n \"Invalid target in header chain\"\n );\n\n startingEpoch = nextEpoch;\n nextEpoch = nullEpoch;\n }\n\n previousHeaderDigest = currentDigest;\n }\n\n return (startingHeaderTimestamp, headerCount);\n }\n\n /// @notice Get the difficulty of the specified block.\n /// @param blockNumber The number of the block. Must fall within the relay\n /// range (at or after the relay genesis, and at or before the end of the\n /// most recent epoch proven to the relay).\n /// @return The difficulty of the epoch.\n function getBlockDifficulty(uint256 blockNumber)\n external\n view\n returns (uint256)\n {\n return getEpochDifficulty(blockNumber / 2016);\n }\n\n /// @notice Get the range of blocks the relay can accept proofs for.\n /// @dev Assumes that the genesis has been set correctly.\n /// Additionally, if the next epoch after the current one has the exact\n /// same difficulty, headers for it can be validated as well.\n /// This function should be used for informative purposes,\n /// e.g. to determine whether a retarget must be provided before submitting\n /// a header chain for validation.\n /// @return relayGenesis The height of the earliest block that can be\n /// included in header chains for the relay to validate.\n /// @return currentEpochEnd The height of the last block that can be\n /// included in header chains for the relay to validate.\n function getRelayRange()\n external\n view\n returns (uint256 relayGenesis, uint256 currentEpochEnd)\n {\n relayGenesis = genesisEpoch * 2016;\n currentEpochEnd = (currentEpoch * 2016) + 2015;\n }\n\n /// @notice Returns the difficulty of the current epoch.\n /// @dev returns 0 if the relay is not ready.\n /// @return The difficulty of the current epoch.\n function getCurrentEpochDifficulty()\n external\n view\n virtual\n returns (uint256)\n {\n return currentEpochDifficulty;\n }\n\n /// @notice Returns the difficulty of the previous epoch.\n /// @dev Returns 0 if the relay is not ready or has not had a retarget.\n /// @return The difficulty of the previous epoch.\n function getPrevEpochDifficulty() external view virtual returns (uint256) {\n return prevEpochDifficulty;\n }\n\n function getCurrentAndPrevEpochDifficulty()\n external\n view\n returns (uint256 current, uint256 previous)\n {\n return (currentEpochDifficulty, prevEpochDifficulty);\n }\n\n /// @notice Get the difficulty of the specified epoch.\n /// @param epochNumber The number of the epoch (the height of the first\n /// block of the epoch, divided by 2016). Must fall within the relay range.\n /// @return The difficulty of the epoch.\n function getEpochDifficulty(uint256 epochNumber)\n public\n view\n returns (uint256)\n {\n require(epochNumber >= genesisEpoch, \"Epoch is before relay genesis\");\n require(\n epochNumber <= currentEpoch,\n \"Epoch is not proven to the relay yet\"\n );\n return BTCUtils.calculateDifficulty(epochs[epochNumber].target);\n }\n\n /// @notice Check that the specified header forms a correct chain with the\n /// digest of the previous header (if provided), and has sufficient work.\n /// @param headers The byte array containing the header of interest.\n /// @param start The start of the header in the array.\n /// @param prevDigest The digest of the previous header\n /// (optional; providing zeros for the digest skips the check).\n /// @return digest The digest of the current header.\n /// @return target The PoW target of the header.\n /// @dev Throws an exception if the header's chain or PoW are invalid.\n /// Performs no other validation.\n function validateHeader(\n bytes memory headers,\n uint256 start,\n bytes32 prevDigest\n ) internal view returns (bytes32 digest, uint256 target) {\n // If previous block digest has been provided, require that it matches\n if (prevDigest != bytes32(0)) {\n require(\n headers.validateHeaderPrevHash(start, prevDigest),\n \"Invalid chain\"\n );\n }\n\n // Require that the header has sufficient work for its stated target\n target = headers.extractTargetAt(start);\n digest = headers.hash256Slice(start, 80);\n require(ValidateSPV.validateHeaderWork(digest, target), \"Invalid work\");\n\n return (digest, target);\n }\n}\n"
327
327
  },
328
+ "contracts/relay/LightRelayMaintainerProxy.sol": {
329
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\n\n// ██████████████ ▐████▌ ██████████████\n// ██████████████ ▐████▌ ██████████████\n// ▐████▌ ▐████▌\n// ▐████▌ ▐████▌\n// ██████████████ ▐████▌ ██████████████\n// ██████████████ ▐████▌ ██████████████\n// ▐████▌ ▐████▌\n// ▐████▌ ▐████▌\n// ▐████▌ ▐████▌\n// ▐████▌ ▐████▌\n// ▐████▌ ▐████▌\n// ▐████▌ ▐████▌\n\npragma solidity 0.8.17;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@keep-network/random-beacon/contracts/Reimbursable.sol\";\nimport \"@keep-network/random-beacon/contracts/ReimbursementPool.sol\";\n\nimport \"./LightRelay.sol\";\n\n/// @title LightRelayMaintainerProxy\n/// @notice The proxy contract that allows the relay maintainers to be refunded\n/// for the spent gas from the `ReimbursementPool`. When proving the\n/// next Bitcoin difficulty epoch, the maintainer calls the\n/// `LightRelayMaintainerProxy` which in turn calls the actual `LightRelay`\n/// contract.\ncontract LightRelayMaintainerProxy is Ownable, Reimbursable {\n ILightRelay public lightRelay;\n\n /// @notice Stores the addresses that can maintain the relay. Those\n /// addresses are attested by the DAO.\n /// @dev The goal is to prevent a griefing attack by frontrunning relay\n /// maintainer which is responsible for retargetting the relay in the\n /// given round. The maintainer's transaction would revert with no gas\n /// refund. Having the ability to restrict maintainer addresses is also\n /// important in case the underlying relay contract has authorization\n /// requirements for callers.\n mapping(address => bool) public isAuthorized;\n\n /// @notice Gas that is meant to balance the retarget overall cost. Can be\n // updated by the governance based on the current market conditions.\n uint256 public retargetGasOffset;\n\n event LightRelayUpdated(address newRelay);\n\n event MaintainerAuthorized(address indexed maintainer);\n\n event MaintainerDeauthorized(address indexed maintainer);\n\n event RetargetGasOffsetUpdated(uint256 retargetGasOffset);\n\n modifier onlyRelayMaintainer() {\n require(isAuthorized[msg.sender], \"Caller is not authorized\");\n _;\n }\n\n modifier onlyReimbursableAdmin() override {\n require(owner() == msg.sender, \"Caller is not the owner\");\n _;\n }\n\n constructor(ILightRelay _lightRelay, ReimbursementPool _reimbursementPool) {\n require(\n address(_lightRelay) != address(0),\n \"Light relay must not be zero address\"\n );\n require(\n address(_reimbursementPool) != address(0),\n \"Reimbursement pool must not be zero address\"\n );\n\n lightRelay = _lightRelay;\n reimbursementPool = _reimbursementPool;\n\n retargetGasOffset = 54000;\n }\n\n /// @notice Allows the governance to upgrade the `LightRelay` address.\n /// @dev The function does not implement any governance delay and does not\n /// check the status of the `LightRelay`. The Governance implementation\n /// needs to ensure all requirements for the upgrade are satisfied\n /// before executing this function.\n function updateLightRelay(ILightRelay _lightRelay) external onlyOwner {\n require(\n address(_lightRelay) != address(0),\n \"New light relay must not be zero address\"\n );\n\n lightRelay = _lightRelay;\n emit LightRelayUpdated(address(_lightRelay));\n }\n\n /// @notice Authorizes the given address as a maintainer. Can only be called\n /// by the owner and the address of the maintainer must not be\n /// already authorized.\n /// @dev The function does not implement any governance delay.\n /// @param maintainer The address of the maintainer to be authorized.\n function authorize(address maintainer) external onlyOwner {\n require(!isAuthorized[maintainer], \"Maintainer is already authorized\");\n\n isAuthorized[maintainer] = true;\n emit MaintainerAuthorized(maintainer);\n }\n\n /// @notice Deauthorizes the given address as a maintainer. Can only be\n /// called by the owner and the address of the maintainer must be\n /// authorized.\n /// @dev The function does not implement any governance delay.\n /// @param maintainer The address of the maintainer to be deauthorized.\n function deauthorize(address maintainer) external onlyOwner {\n require(isAuthorized[maintainer], \"Maintainer is not authorized\");\n\n isAuthorized[maintainer] = false;\n emit MaintainerDeauthorized(maintainer);\n }\n\n /// @notice Updates the values of retarget gas offset.\n /// @dev Can be called only by the contract owner. The caller is responsible\n /// for validating the parameter. The function does not implement any\n /// governance delay.\n /// @param newRetargetGasOffset New retarget gas offset.\n function updateRetargetGasOffset(uint256 newRetargetGasOffset)\n external\n onlyOwner\n {\n retargetGasOffset = newRetargetGasOffset;\n emit RetargetGasOffsetUpdated(retargetGasOffset);\n }\n\n /// @notice Wraps `LightRelay.retarget` call and reimburses the caller's\n /// transaction cost. Can only be called by an authorized relay\n /// maintainer.\n /// @dev See `LightRelay.retarget` function documentation.\n function retarget(bytes memory headers) external onlyRelayMaintainer {\n uint256 gasStart = gasleft();\n\n lightRelay.retarget(headers);\n\n reimbursementPool.refund(\n (gasStart - gasleft()) + retargetGasOffset,\n msg.sender\n );\n }\n}\n"
330
+ },
328
331
  "contracts/test/BankStub.sol": {
329
332
  "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity 0.8.17;\n\nimport \"../bank/Bank.sol\";\n\ncontract BankStub is Bank {\n function setBalance(address addr, uint256 amount) external {\n balanceOf[addr] = amount;\n }\n}\n"
330
333
  },
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -0,0 +1,4 @@
1
+ {
2
+ "_format": "hh-sol-dbg-1",
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
+ }
@@ -0,0 +1,280 @@
1
+ {
2
+ "_format": "hh-sol-artifact-1",
3
+ "contractName": "LightRelayMaintainerProxy",
4
+ "sourceName": "contracts/relay/LightRelayMaintainerProxy.sol",
5
+ "abi": [
6
+ {
7
+ "inputs": [
8
+ {
9
+ "internalType": "contract ILightRelay",
10
+ "name": "_lightRelay",
11
+ "type": "address"
12
+ },
13
+ {
14
+ "internalType": "contract ReimbursementPool",
15
+ "name": "_reimbursementPool",
16
+ "type": "address"
17
+ }
18
+ ],
19
+ "stateMutability": "nonpayable",
20
+ "type": "constructor"
21
+ },
22
+ {
23
+ "anonymous": false,
24
+ "inputs": [
25
+ {
26
+ "indexed": false,
27
+ "internalType": "address",
28
+ "name": "newRelay",
29
+ "type": "address"
30
+ }
31
+ ],
32
+ "name": "LightRelayUpdated",
33
+ "type": "event"
34
+ },
35
+ {
36
+ "anonymous": false,
37
+ "inputs": [
38
+ {
39
+ "indexed": true,
40
+ "internalType": "address",
41
+ "name": "maintainer",
42
+ "type": "address"
43
+ }
44
+ ],
45
+ "name": "MaintainerAuthorized",
46
+ "type": "event"
47
+ },
48
+ {
49
+ "anonymous": false,
50
+ "inputs": [
51
+ {
52
+ "indexed": true,
53
+ "internalType": "address",
54
+ "name": "maintainer",
55
+ "type": "address"
56
+ }
57
+ ],
58
+ "name": "MaintainerDeauthorized",
59
+ "type": "event"
60
+ },
61
+ {
62
+ "anonymous": false,
63
+ "inputs": [
64
+ {
65
+ "indexed": true,
66
+ "internalType": "address",
67
+ "name": "previousOwner",
68
+ "type": "address"
69
+ },
70
+ {
71
+ "indexed": true,
72
+ "internalType": "address",
73
+ "name": "newOwner",
74
+ "type": "address"
75
+ }
76
+ ],
77
+ "name": "OwnershipTransferred",
78
+ "type": "event"
79
+ },
80
+ {
81
+ "anonymous": false,
82
+ "inputs": [
83
+ {
84
+ "indexed": false,
85
+ "internalType": "address",
86
+ "name": "newReimbursementPool",
87
+ "type": "address"
88
+ }
89
+ ],
90
+ "name": "ReimbursementPoolUpdated",
91
+ "type": "event"
92
+ },
93
+ {
94
+ "anonymous": false,
95
+ "inputs": [
96
+ {
97
+ "indexed": false,
98
+ "internalType": "uint256",
99
+ "name": "retargetGasOffset",
100
+ "type": "uint256"
101
+ }
102
+ ],
103
+ "name": "RetargetGasOffsetUpdated",
104
+ "type": "event"
105
+ },
106
+ {
107
+ "inputs": [
108
+ {
109
+ "internalType": "address",
110
+ "name": "maintainer",
111
+ "type": "address"
112
+ }
113
+ ],
114
+ "name": "authorize",
115
+ "outputs": [],
116
+ "stateMutability": "nonpayable",
117
+ "type": "function"
118
+ },
119
+ {
120
+ "inputs": [
121
+ {
122
+ "internalType": "address",
123
+ "name": "maintainer",
124
+ "type": "address"
125
+ }
126
+ ],
127
+ "name": "deauthorize",
128
+ "outputs": [],
129
+ "stateMutability": "nonpayable",
130
+ "type": "function"
131
+ },
132
+ {
133
+ "inputs": [
134
+ {
135
+ "internalType": "address",
136
+ "name": "",
137
+ "type": "address"
138
+ }
139
+ ],
140
+ "name": "isAuthorized",
141
+ "outputs": [
142
+ {
143
+ "internalType": "bool",
144
+ "name": "",
145
+ "type": "bool"
146
+ }
147
+ ],
148
+ "stateMutability": "view",
149
+ "type": "function"
150
+ },
151
+ {
152
+ "inputs": [],
153
+ "name": "lightRelay",
154
+ "outputs": [
155
+ {
156
+ "internalType": "contract ILightRelay",
157
+ "name": "",
158
+ "type": "address"
159
+ }
160
+ ],
161
+ "stateMutability": "view",
162
+ "type": "function"
163
+ },
164
+ {
165
+ "inputs": [],
166
+ "name": "owner",
167
+ "outputs": [
168
+ {
169
+ "internalType": "address",
170
+ "name": "",
171
+ "type": "address"
172
+ }
173
+ ],
174
+ "stateMutability": "view",
175
+ "type": "function"
176
+ },
177
+ {
178
+ "inputs": [],
179
+ "name": "reimbursementPool",
180
+ "outputs": [
181
+ {
182
+ "internalType": "contract ReimbursementPool",
183
+ "name": "",
184
+ "type": "address"
185
+ }
186
+ ],
187
+ "stateMutability": "view",
188
+ "type": "function"
189
+ },
190
+ {
191
+ "inputs": [],
192
+ "name": "renounceOwnership",
193
+ "outputs": [],
194
+ "stateMutability": "nonpayable",
195
+ "type": "function"
196
+ },
197
+ {
198
+ "inputs": [
199
+ {
200
+ "internalType": "bytes",
201
+ "name": "headers",
202
+ "type": "bytes"
203
+ }
204
+ ],
205
+ "name": "retarget",
206
+ "outputs": [],
207
+ "stateMutability": "nonpayable",
208
+ "type": "function"
209
+ },
210
+ {
211
+ "inputs": [],
212
+ "name": "retargetGasOffset",
213
+ "outputs": [
214
+ {
215
+ "internalType": "uint256",
216
+ "name": "",
217
+ "type": "uint256"
218
+ }
219
+ ],
220
+ "stateMutability": "view",
221
+ "type": "function"
222
+ },
223
+ {
224
+ "inputs": [
225
+ {
226
+ "internalType": "address",
227
+ "name": "newOwner",
228
+ "type": "address"
229
+ }
230
+ ],
231
+ "name": "transferOwnership",
232
+ "outputs": [],
233
+ "stateMutability": "nonpayable",
234
+ "type": "function"
235
+ },
236
+ {
237
+ "inputs": [
238
+ {
239
+ "internalType": "contract ILightRelay",
240
+ "name": "_lightRelay",
241
+ "type": "address"
242
+ }
243
+ ],
244
+ "name": "updateLightRelay",
245
+ "outputs": [],
246
+ "stateMutability": "nonpayable",
247
+ "type": "function"
248
+ },
249
+ {
250
+ "inputs": [
251
+ {
252
+ "internalType": "contract ReimbursementPool",
253
+ "name": "_reimbursementPool",
254
+ "type": "address"
255
+ }
256
+ ],
257
+ "name": "updateReimbursementPool",
258
+ "outputs": [],
259
+ "stateMutability": "nonpayable",
260
+ "type": "function"
261
+ },
262
+ {
263
+ "inputs": [
264
+ {
265
+ "internalType": "uint256",
266
+ "name": "newRetargetGasOffset",
267
+ "type": "uint256"
268
+ }
269
+ ],
270
+ "name": "updateRetargetGasOffset",
271
+ "outputs": [],
272
+ "stateMutability": "nonpayable",
273
+ "type": "function"
274
+ }
275
+ ],
276
+ "bytecode": "0x608060405234801561001057600080fd5b50604051610c2c380380610c2c83398101604081905261002f916101a8565b61003833610140565b6001600160a01b03821661009f5760405162461bcd60e51b8152602060048201526024808201527f4c696768742072656c6179206d757374206e6f74206265207a65726f206164646044820152637265737360e01b60648201526084015b60405180910390fd5b6001600160a01b0381166101095760405162461bcd60e51b815260206004820152602b60248201527f5265696d62757273656d656e7420706f6f6c206d757374206e6f74206265207a60448201526a65726f206164647265737360a81b6064820152608401610096565b603380546001600160a01b039384166001600160a01b0319918216179091556001805492909316911617905561d2f06035556101e2565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146101a557600080fd5b50565b600080604083850312156101bb57600080fd5b82516101c681610190565b60208401519092506101d781610190565b809150509250929050565b610a3b806101f16000396000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c80638da5cb5b1161008c578063b6a5d7de11610066578063b6a5d7de146101a5578063c09975cd146101b8578063f2fde38b146101cb578063fe9fbb80146101de57600080fd5b80638da5cb5b1461016e5780639d5f29df1461017f578063b214b4981461019257600080fd5b80637b35b4e6116100bd5780637b35b4e61461011d5780637ca5b1dd1461013057806384dc44091461014357600080fd5b806327c97fa5146100e4578063293aa4a2146100f9578063715018a614610115575b600080fd5b6100f76100f2366004610871565b610211565b005b61010260355481565b6040519081526020015b60405180910390f35b6100f76102cf565b6100f761012b366004610871565b6102e3565b6100f761013e3660046108ab565b6103b7565b603354610156906001600160a01b031681565b6040516001600160a01b03909116815260200161010c565b6000546001600160a01b0316610156565b6100f761018d366004610871565b610535565b6100f76101a036600461095c565b61061b565b6100f76101b3366004610871565b610658565b600154610156906001600160a01b031681565b6100f76101d9366004610871565b610715565b6102016101ec366004610871565b60346020526000908152604090205460ff1681565b604051901515815260200161010c565b6102196107a5565b6001600160a01b03811660009081526034602052604090205460ff166102865760405162461bcd60e51b815260206004820152601c60248201527f4d61696e7461696e6572206973206e6f7420617574686f72697a65640000000060448201526064015b60405180910390fd5b6001600160a01b038116600081815260346020526040808220805460ff19169055517fc74b7e7972a420ccf708a44401a97c1bcaacb21a25a1e0f83ee40841654b2ec89190a250565b6102d76107a5565b6102e160006107ff565b565b336102f66000546001600160a01b031690565b6001600160a01b03161461034c5760405162461bcd60e51b815260206004820152601760248201527f43616c6c6572206973206e6f7420746865206f776e6572000000000000000000604482015260640161027d565b6040516001600160a01b03821681527f0e2d2343d31b085b7c4e56d1c8a6ec79f7ab07460386f1c9a1756239fe2533ac9060200160405180910390a16001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b3360009081526034602052604090205460ff166104165760405162461bcd60e51b815260206004820152601860248201527f43616c6c6572206973206e6f7420617574686f72697a65640000000000000000604482015260640161027d565b60005a6033546040517f7ca5b1dd0000000000000000000000000000000000000000000000000000000081529192506001600160a01b031690637ca5b1dd90610463908590600401610975565b600060405180830381600087803b15801561047d57600080fd5b505af1158015610491573d6000803e3d6000fd5b50506001546035546001600160a01b039091169250637ad226dc91505a6104b890856109d9565b6104c291906109f2565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526004810191909152336024820152604401600060405180830381600087803b15801561051957600080fd5b505af115801561052d573d6000803e3d6000fd5b505050505050565b61053d6107a5565b6001600160a01b0381166105b95760405162461bcd60e51b815260206004820152602860248201527f4e6577206c696768742072656c6179206d757374206e6f74206265207a65726f60448201527f2061646472657373000000000000000000000000000000000000000000000000606482015260840161027d565b6033805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fa46f2602ab8b56454b3c3f2ac8bbad3a47d901cc73f0d800b2d607eb68743428906020015b60405180910390a150565b6106236107a5565b60358190556040518181527f47498a8064df4e0fae8efc492d7ce3222dc1dc415d1e1ff688a327ff101940fd90602001610610565b6106606107a5565b6001600160a01b03811660009081526034602052604090205460ff16156106c95760405162461bcd60e51b815260206004820181905260248201527f4d61696e7461696e657220697320616c726561647920617574686f72697a6564604482015260640161027d565b6001600160a01b038116600081815260346020526040808220805460ff19166001179055517fd47aed730622d4816ba8c667c5644d30d0042568ce573955dfa5cafd60ecba4b9190a250565b61071d6107a5565b6001600160a01b0381166107995760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161027d565b6107a2816107ff565b50565b6000546001600160a01b031633146102e15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161027d565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146107a257600080fd5b60006020828403121561088357600080fd5b813561088e8161085c565b9392505050565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156108bd57600080fd5b813567ffffffffffffffff808211156108d557600080fd5b818401915084601f8301126108e957600080fd5b8135818111156108fb576108fb610895565b604051601f8201601f19908116603f0116810190838211818310171561092357610923610895565b8160405282815287602084870101111561093c57600080fd5b826020860160208301376000928101602001929092525095945050505050565b60006020828403121561096e57600080fd5b5035919050565b600060208083528351808285015260005b818110156109a257858101830151858201604001528201610986565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052601160045260246000fd5b818103818111156109ec576109ec6109c3565b92915050565b808201808211156109ec576109ec6109c356fea26469706673582212204c1db717ea81f3512cc4bba5e616ce0d380223671e65b946c7b271b3c789ec1064736f6c63430008110033",
277
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100df5760003560e01c80638da5cb5b1161008c578063b6a5d7de11610066578063b6a5d7de146101a5578063c09975cd146101b8578063f2fde38b146101cb578063fe9fbb80146101de57600080fd5b80638da5cb5b1461016e5780639d5f29df1461017f578063b214b4981461019257600080fd5b80637b35b4e6116100bd5780637b35b4e61461011d5780637ca5b1dd1461013057806384dc44091461014357600080fd5b806327c97fa5146100e4578063293aa4a2146100f9578063715018a614610115575b600080fd5b6100f76100f2366004610871565b610211565b005b61010260355481565b6040519081526020015b60405180910390f35b6100f76102cf565b6100f761012b366004610871565b6102e3565b6100f761013e3660046108ab565b6103b7565b603354610156906001600160a01b031681565b6040516001600160a01b03909116815260200161010c565b6000546001600160a01b0316610156565b6100f761018d366004610871565b610535565b6100f76101a036600461095c565b61061b565b6100f76101b3366004610871565b610658565b600154610156906001600160a01b031681565b6100f76101d9366004610871565b610715565b6102016101ec366004610871565b60346020526000908152604090205460ff1681565b604051901515815260200161010c565b6102196107a5565b6001600160a01b03811660009081526034602052604090205460ff166102865760405162461bcd60e51b815260206004820152601c60248201527f4d61696e7461696e6572206973206e6f7420617574686f72697a65640000000060448201526064015b60405180910390fd5b6001600160a01b038116600081815260346020526040808220805460ff19169055517fc74b7e7972a420ccf708a44401a97c1bcaacb21a25a1e0f83ee40841654b2ec89190a250565b6102d76107a5565b6102e160006107ff565b565b336102f66000546001600160a01b031690565b6001600160a01b03161461034c5760405162461bcd60e51b815260206004820152601760248201527f43616c6c6572206973206e6f7420746865206f776e6572000000000000000000604482015260640161027d565b6040516001600160a01b03821681527f0e2d2343d31b085b7c4e56d1c8a6ec79f7ab07460386f1c9a1756239fe2533ac9060200160405180910390a16001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b3360009081526034602052604090205460ff166104165760405162461bcd60e51b815260206004820152601860248201527f43616c6c6572206973206e6f7420617574686f72697a65640000000000000000604482015260640161027d565b60005a6033546040517f7ca5b1dd0000000000000000000000000000000000000000000000000000000081529192506001600160a01b031690637ca5b1dd90610463908590600401610975565b600060405180830381600087803b15801561047d57600080fd5b505af1158015610491573d6000803e3d6000fd5b50506001546035546001600160a01b039091169250637ad226dc91505a6104b890856109d9565b6104c291906109f2565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526004810191909152336024820152604401600060405180830381600087803b15801561051957600080fd5b505af115801561052d573d6000803e3d6000fd5b505050505050565b61053d6107a5565b6001600160a01b0381166105b95760405162461bcd60e51b815260206004820152602860248201527f4e6577206c696768742072656c6179206d757374206e6f74206265207a65726f60448201527f2061646472657373000000000000000000000000000000000000000000000000606482015260840161027d565b6033805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fa46f2602ab8b56454b3c3f2ac8bbad3a47d901cc73f0d800b2d607eb68743428906020015b60405180910390a150565b6106236107a5565b60358190556040518181527f47498a8064df4e0fae8efc492d7ce3222dc1dc415d1e1ff688a327ff101940fd90602001610610565b6106606107a5565b6001600160a01b03811660009081526034602052604090205460ff16156106c95760405162461bcd60e51b815260206004820181905260248201527f4d61696e7461696e657220697320616c726561647920617574686f72697a6564604482015260640161027d565b6001600160a01b038116600081815260346020526040808220805460ff19166001179055517fd47aed730622d4816ba8c667c5644d30d0042568ce573955dfa5cafd60ecba4b9190a250565b61071d6107a5565b6001600160a01b0381166107995760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161027d565b6107a2816107ff565b50565b6000546001600160a01b031633146102e15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161027d565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146107a257600080fd5b60006020828403121561088357600080fd5b813561088e8161085c565b9392505050565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156108bd57600080fd5b813567ffffffffffffffff808211156108d557600080fd5b818401915084601f8301126108e957600080fd5b8135818111156108fb576108fb610895565b604051601f8201601f19908116603f0116810190838211818310171561092357610923610895565b8160405282815287602084870101111561093c57600080fd5b826020860160208301376000928101602001929092525095945050505050565b60006020828403121561096e57600080fd5b5035919050565b600060208083528351808285015260005b818110156109a257858101830151858201604001528201610986565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052601160045260246000fd5b818103818111156109ec576109ec6109c3565b92915050565b808201808211156109ec576109ec6109c356fea26469706673582212204c1db717ea81f3512cc4bba5e616ce0d380223671e65b946c7b271b3c789ec1064736f6c63430008110033",
278
+ "linkReferences": {},
279
+ "deployedLinkReferences": {}
280
+ }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/d1d06b615610162a2e80a9362741427b.json"
3
+ "buildInfo": "../../../build-info/4dae352543b4d68232673fef698e9426.json"
4
4
  }