From 765e4bcaa4bb49f9f899134afd2ace482b165091 Mon Sep 17 00:00:00 2001 From: nxqbao Date: Thu, 15 Dec 2022 11:27:06 +0700 Subject: [PATCH 1/4] Init commit --- .../sequential-governance/CoreGovernance.sol | 5 +- test/governance-admin/GovernanceAdmin.test.ts | 145 +++++++++++++----- 2 files changed, 112 insertions(+), 38 deletions(-) diff --git a/contracts/extensions/sequential-governance/CoreGovernance.sol b/contracts/extensions/sequential-governance/CoreGovernance.sol index 7527ca7df..196bfe91b 100644 --- a/contracts/extensions/sequential-governance/CoreGovernance.sol +++ b/contracts/extensions/sequential-governance/CoreGovernance.sol @@ -285,7 +285,10 @@ abstract contract CoreGovernance is SignatureConsumer, VoteStatusConsumer, Chain * @dev When the contract is on Ronin chain, checks whether the proposal is expired and delete it if is expired. */ function _tryDeleteExpiredVotingRound(ProposalVote storage _proposalVote) private returns (bool _isExpired) { - _isExpired = _getChainType() == ChainType.RoninChain && _proposalVote.expiryTimestamp <= block.timestamp; + _isExpired = + _getChainType() == ChainType.RoninChain && + _proposalVote.status == VoteStatus.Pending && + _proposalVote.expiryTimestamp <= block.timestamp; if (_isExpired) { emit ProposalExpired(_proposalVote.hash); diff --git a/test/governance-admin/GovernanceAdmin.test.ts b/test/governance-admin/GovernanceAdmin.test.ts index 6e3ed5757..74e981779 100644 --- a/test/governance-admin/GovernanceAdmin.test.ts +++ b/test/governance-admin/GovernanceAdmin.test.ts @@ -260,18 +260,16 @@ describe('Governance Admin test', () => { it('Should the expired proposal cannot be voted anymore', async () => { const newMinValidatorStakingAmount = 1337; const latestTimestamp = await getLastBlockTimestamp(); - const expiryTimestamp = latestTimestamp + proposalExpiryDuration, - proposal = await governanceAdminInterface.createProposal( - expiryTimestamp, - stakingContract.address, - 0, - governanceAdminInterface.interface.encodeFunctionData('functionDelegateCall', [ - stakingContract.interface.encodeFunctionData('setMinValidatorStakingAmount', [ - newMinValidatorStakingAmount, - ]), - ]), - 500_000 - ); + const expiryTimestamp = latestTimestamp + proposalExpiryDuration; + proposal = await governanceAdminInterface.createProposal( + expiryTimestamp, + stakingContract.address, + 0, + governanceAdminInterface.interface.encodeFunctionData('functionDelegateCall', [ + stakingContract.interface.encodeFunctionData('setMinValidatorStakingAmount', [newMinValidatorStakingAmount]), + ]), + 500_000 + ); previousProposal = proposal; previousHash = getProposalHash(proposal); @@ -313,19 +311,17 @@ describe('Governance Admin test', () => { const newMinValidatorStakingAmount = 202881; const latestTimestamp = await getLastBlockTimestamp(); - const expiryTimestamp = latestTimestamp + proposalExpiryDuration, - proposal = await governanceAdminInterface.createProposal( - expiryTimestamp, - stakingContract.address, - 0, - governanceAdminInterface.interface.encodeFunctionData('functionDelegateCall', [ - stakingContract.interface.encodeFunctionData('setMinValidatorStakingAmount', [ - newMinValidatorStakingAmount, - ]), - ]), - 500_000, - BigNumber.from(previousProposal.nonce) - ); + const expiryTimestamp = latestTimestamp + proposalExpiryDuration; + proposal = await governanceAdminInterface.createProposal( + expiryTimestamp, + stakingContract.address, + 0, + governanceAdminInterface.interface.encodeFunctionData('functionDelegateCall', [ + stakingContract.interface.encodeFunctionData('setMinValidatorStakingAmount', [newMinValidatorStakingAmount]), + ]), + 500_000, + BigNumber.from(previousProposal.nonce) + ); previousSignatures = signatures = await governanceAdminInterface.generateSignatures(proposal); previousSupports = supports = signatures.map(() => VoteType.For); @@ -359,18 +355,16 @@ describe('Governance Admin test', () => { it('Should the expired proposal can be manually marked as expired', async () => { const newMinValidatorStakingAmount = 989283; const latestTimestamp = await getLastBlockTimestamp(); - const expiryTimestamp = latestTimestamp + proposalExpiryDuration, - proposal = await governanceAdminInterface.createProposal( - expiryTimestamp, - stakingContract.address, - 0, - governanceAdminInterface.interface.encodeFunctionData('functionDelegateCall', [ - stakingContract.interface.encodeFunctionData('setMinValidatorStakingAmount', [ - newMinValidatorStakingAmount, - ]), - ]), - 500_000 - ); + const expiryTimestamp = latestTimestamp + proposalExpiryDuration; + proposal = await governanceAdminInterface.createProposal( + expiryTimestamp, + stakingContract.address, + 0, + governanceAdminInterface.interface.encodeFunctionData('functionDelegateCall', [ + stakingContract.interface.encodeFunctionData('setMinValidatorStakingAmount', [newMinValidatorStakingAmount]), + ]), + 500_000 + ); previousProposal = proposal; previousHash = getProposalHash(proposal); @@ -414,5 +408,82 @@ describe('Governance Admin test', () => { expect(currentProposalVote.hash).eq(ZERO_BYTES32); expect(currentProposalVote.status).eq(VoteStatus.Pending); }); + + it('Should a proposal executed, then expiry time passes, and then a new proposal is created and executed', async () => { + // Execute a proposal + let currentProposalVote = await governanceAdmin.vote(previousProposal.chainId, previousProposal.nonce); + expect(currentProposalVote.hash).eq(ZERO_BYTES32); + expect(currentProposalVote.status).eq(VoteStatus.Pending); + + let newMinValidatorStakingAmount = 191293002; + let latestTimestamp = await getLastBlockTimestamp(); + let expiryTimestamp = latestTimestamp + proposalExpiryDuration; + proposal = await governanceAdminInterface.createProposal( + expiryTimestamp, + stakingContract.address, + 0, + governanceAdminInterface.interface.encodeFunctionData('functionDelegateCall', [ + stakingContract.interface.encodeFunctionData('setMinValidatorStakingAmount', [newMinValidatorStakingAmount]), + ]), + 500_000, + BigNumber.from(previousProposal.nonce) + ); + expect(proposal.nonce).eq(previousProposal.nonce); + + previousSignatures = signatures = await governanceAdminInterface.generateSignatures(proposal); + previousSupports = supports = signatures.map(() => VoteType.For); + + await governanceAdmin + .connect(trustedOrgs[0].governor) + .proposeProposalStructAndCastVotes(proposal, supports.splice(0, 1), signatures.splice(0, 1)); + + currentProposalVote = await governanceAdmin.vote(previousProposal.chainId, previousProposal.nonce); + expect(currentProposalVote.status).eq(VoteStatus.Pending); + + await governanceAdmin.connect(trustedOrgs[0].governor).castProposalBySignatures(proposal, supports, signatures); + currentProposalVote = await governanceAdmin.vote(previousProposal.chainId, previousProposal.nonce); + expect(currentProposalVote.status).eq(VoteStatus.Executed); + + previousProposal = proposal; + previousHash = getProposalHash(proposal); + + // Wait to expiry time pass + await network.provider.send('evm_setNextBlockTimestamp', [expiryTimestamp + 1]); + + // Create a new proposal + currentProposalVote = await governanceAdmin.vote(previousProposal.chainId, previousProposal.nonce); + expect(currentProposalVote.hash).eq(previousHash); + expect(currentProposalVote.status).eq(VoteStatus.Executed); + + newMinValidatorStakingAmount = 491239; + latestTimestamp = await getLastBlockTimestamp(); + expiryTimestamp = latestTimestamp + proposalExpiryDuration; + proposal = await governanceAdminInterface.createProposal( + expiryTimestamp, + stakingContract.address, + 0, + governanceAdminInterface.interface.encodeFunctionData('functionDelegateCall', [ + stakingContract.interface.encodeFunctionData('setMinValidatorStakingAmount', [newMinValidatorStakingAmount]), + ]), + 500_000 + ); + expect(proposal.nonce).eq(BigNumber.from(previousProposal.nonce).add(1)); + + previousSignatures = signatures = await governanceAdminInterface.generateSignatures(proposal); + previousSupports = supports = signatures.map(() => VoteType.For); + previousProposal = proposal; + previousHash = getProposalHash(proposal); + + await governanceAdmin + .connect(trustedOrgs[0].governor) + .proposeProposalStructAndCastVotes(proposal, supports.splice(0, 1), signatures.splice(0, 1)); + + currentProposalVote = await governanceAdmin.vote(previousProposal.chainId, previousProposal.nonce); + expect(currentProposalVote.status).eq(VoteStatus.Pending); + + await governanceAdmin.connect(trustedOrgs[0].governor).castProposalBySignatures(proposal, supports, signatures); + currentProposalVote = await governanceAdmin.vote(previousProposal.chainId, previousProposal.nonce); + expect(currentProposalVote.status).eq(VoteStatus.Executed); + }); }); }); From 27e1f71e8db8a28038ee3390ce4f296a319c40cb Mon Sep 17 00:00:00 2001 From: nxqbao Date: Thu, 15 Dec 2022 11:59:07 +0700 Subject: [PATCH 2/4] Fix test --- test/governance-admin/GovernanceAdmin.test.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/governance-admin/GovernanceAdmin.test.ts b/test/governance-admin/GovernanceAdmin.test.ts index 74e981779..e6aab6050 100644 --- a/test/governance-admin/GovernanceAdmin.test.ts +++ b/test/governance-admin/GovernanceAdmin.test.ts @@ -448,7 +448,8 @@ describe('Governance Admin test', () => { previousHash = getProposalHash(proposal); // Wait to expiry time pass - await network.provider.send('evm_setNextBlockTimestamp', [expiryTimestamp + 1]); + let nextBlockTimestamp = expiryTimestamp + 1; + await network.provider.send('evm_setNextBlockTimestamp', [nextBlockTimestamp]); // Create a new proposal currentProposalVote = await governanceAdmin.vote(previousProposal.chainId, previousProposal.nonce); @@ -456,8 +457,8 @@ describe('Governance Admin test', () => { expect(currentProposalVote.status).eq(VoteStatus.Executed); newMinValidatorStakingAmount = 491239; - latestTimestamp = await getLastBlockTimestamp(); - expiryTimestamp = latestTimestamp + proposalExpiryDuration; + expiryTimestamp = nextBlockTimestamp + proposalExpiryDuration; + proposal = await governanceAdminInterface.createProposal( expiryTimestamp, stakingContract.address, From e58ed8b73ec66c2ec735329f040e443f4e4db1f0 Mon Sep 17 00:00:00 2001 From: Bao Date: Thu, 15 Dec 2022 10:26:41 +0700 Subject: [PATCH 3/4] [Staking] Support fetch pool address from pool admin address (#118) Add `getPoolAddressOf` --- contracts/interfaces/staking/IBaseStaking.sol | 5 +++++ contracts/ronin/staking/BaseStaking.sol | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/contracts/interfaces/staking/IBaseStaking.sol b/contracts/interfaces/staking/IBaseStaking.sol index 624d5fc26..2bd2d6999 100644 --- a/contracts/interfaces/staking/IBaseStaking.sol +++ b/contracts/interfaces/staking/IBaseStaking.sol @@ -28,6 +28,11 @@ interface IBaseStaking { */ function isActivePoolAdmin(address _poolAdminAddr) external view returns (bool); + /** + * @dev Returns the consensus address corresponding to the pool admin. + */ + function getPoolAddressOf(address _poolAdminAddr) external view returns (address); + /** * @dev Returns The cooldown time in seconds to undelegate from the last timestamp (s)he delegated. */ diff --git a/contracts/ronin/staking/BaseStaking.sol b/contracts/ronin/staking/BaseStaking.sol index 03d59d35e..cc5c273a7 100644 --- a/contracts/ronin/staking/BaseStaking.sol +++ b/contracts/ronin/staking/BaseStaking.sol @@ -24,7 +24,7 @@ abstract contract BaseStaking is /// @dev The number of seconds that a candidate must wait to be revoked and take the self-staking amount back. uint256 internal _waitingSecsToRevoke; - /// @dev Mapping from pool admin address => consensus address. + /// @dev Mapping from active pool admin address => consensus address. mapping(address => address) internal _activePoolAdminMapping; /** * @dev This empty reserved space is put in place to allow future versions to add new @@ -59,6 +59,13 @@ abstract contract BaseStaking is return _activePoolAdminMapping[_poolAdminAddr] != address(0); } + /** + * @inheritdoc IBaseStaking + */ + function getPoolAddressOf(address _poolAdminAddr) external view override returns (address) { + return _activePoolAdminMapping[_poolAdminAddr]; + } + /** * @inheritdoc IRewardPool */ From ba3d3d2b7df4a0f33c44bc9ca28ad52804cc5c99 Mon Sep 17 00:00:00 2001 From: minh-bq <97180373+minh-bq@users.noreply.github.com> Date: Thu, 15 Dec 2022 14:22:37 +0700 Subject: [PATCH 4/4] Add deployment artifacts for upgraded RoninGovernanceAdmin, Staking (#123) --- .../ronin-testnet/RoninGovernanceAdmin.json | 78 +-- deployments/ronin-testnet/StakingLogic.json | 156 +++--- .../9c14b324033beb5ee990c4b68d9e780e.json | 485 ++++++++++++++++++ 3 files changed, 613 insertions(+), 106 deletions(-) create mode 100644 deployments/ronin-testnet/solcInputs/9c14b324033beb5ee990c4b68d9e780e.json diff --git a/deployments/ronin-testnet/RoninGovernanceAdmin.json b/deployments/ronin-testnet/RoninGovernanceAdmin.json index 367ae1e01..24e03dc08 100644 --- a/deployments/ronin-testnet/RoninGovernanceAdmin.json +++ b/deployments/ronin-testnet/RoninGovernanceAdmin.json @@ -1,5 +1,5 @@ { - "address": "0x6D22328422509F4fe5539e34D15Bf44F47A9df9F", + "address": "0x69F7F0765a347DC4497E948D2c74f9bC328871EC", "abi": [ { "inputs": [ @@ -1145,44 +1145,44 @@ "type": "function" } ], - "transactionHash": "0x7136b4f159e79a157e27c3947dfffb316808e63f6c552fdb5b6b888426e5bd28", + "transactionHash": "0x6b65ebcdb0c067e24f59e138796b9ba03240b03ff2607d3dfaf49abd557b2a3b", "receipt": { "to": null, "from": "0x968D0Cd7343f711216817E617d3f92a23dC91c07", - "contractAddress": "0x6D22328422509F4fe5539e34D15Bf44F47A9df9F", + "contractAddress": "0x69F7F0765a347DC4497E948D2c74f9bC328871EC", "transactionIndex": 0, - "gasUsed": "4245237", - "logsBloom": "0x00000000000000000000010000000000000000000000040000000000000000000000000010000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000800000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x07c7eeb3b703eaaee9d235e205ed7a1b95775c0ead27c36d6527db714c0e6d07", - "transactionHash": "0x7136b4f159e79a157e27c3947dfffb316808e63f6c552fdb5b6b888426e5bd28", + "gasUsed": "4253022", + "logsBloom": "0x00000000000000000000010000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000800000000000000000000000000000000000000000000000002000000000000000000000040000000000000000000000000000000000000000000000", + "blockHash": "0x3415e5691487e7c33b4703c5b015b3340c7250957d6eda2cb9e754629b1346a8", + "transactionHash": "0x6b65ebcdb0c067e24f59e138796b9ba03240b03ff2607d3dfaf49abd557b2a3b", "logs": [ { "transactionIndex": 0, - "blockNumber": 12454562, - "transactionHash": "0x7136b4f159e79a157e27c3947dfffb316808e63f6c552fdb5b6b888426e5bd28", - "address": "0x6D22328422509F4fe5539e34D15Bf44F47A9df9F", + "blockNumber": 12507779, + "transactionHash": "0x6b65ebcdb0c067e24f59e138796b9ba03240b03ff2607d3dfaf49abd557b2a3b", + "address": "0x69F7F0765a347DC4497E948D2c74f9bC328871EC", "topics": [ "0xfd6f5f93d69a07c593a09be0b208bff13ab4ffd6017df3b33433d63bdc59b4d7" ], "data": "0x0000000000000000000000007f46c5dd5f13ff0dd973317411d70800db248e7d", "logIndex": 0, - "blockHash": "0x07c7eeb3b703eaaee9d235e205ed7a1b95775c0ead27c36d6527db714c0e6d07" + "blockHash": "0x3415e5691487e7c33b4703c5b015b3340c7250957d6eda2cb9e754629b1346a8" }, { "transactionIndex": 0, - "blockNumber": 12454562, - "transactionHash": "0x7136b4f159e79a157e27c3947dfffb316808e63f6c552fdb5b6b888426e5bd28", - "address": "0x6D22328422509F4fe5539e34D15Bf44F47A9df9F", + "blockNumber": 12507779, + "transactionHash": "0x6b65ebcdb0c067e24f59e138796b9ba03240b03ff2607d3dfaf49abd557b2a3b", + "address": "0x69F7F0765a347DC4497E948D2c74f9bC328871EC", "topics": [ "0x5cbd8a0bb00196365d5eb3457c6734e7f06666c3c78e5469b4c9deec7edae048" ], "data": "0x000000000000000000000000cee681c9108c42c710c6a8a949307d5f13c9f3ca", "logIndex": 1, - "blockHash": "0x07c7eeb3b703eaaee9d235e205ed7a1b95775c0ead27c36d6527db714c0e6d07" + "blockHash": "0x3415e5691487e7c33b4703c5b015b3340c7250957d6eda2cb9e754629b1346a8" } ], - "blockNumber": 12454562, - "cumulativeGasUsed": "4245237", + "blockNumber": 12507779, + "cumulativeGasUsed": "4253022", "status": 1, "byzantium": true }, @@ -1191,11 +1191,11 @@ "0xCee681C9108c42C710c6A8A949307D5F13C9F3ca", 1209600 ], - "numDeployments": 2, - "solcInputHash": "306cfcffeca66af05c8925f3663c976b", - "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_roninTrustedOrganizationContract\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bridgeContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_proposalExpiryDuration\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"BridgeContractUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_period\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"_operators\",\"type\":\"address[]\"}],\"name\":\"BridgeOperatorsApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"round\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"targets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasAmounts\",\"type\":\"uint256[]\"}],\"indexed\":false,\"internalType\":\"struct Proposal.ProposalDetail\",\"name\":\"proposal\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"globalProposalHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"enum GlobalProposal.TargetOption[]\",\"name\":\"targetOptions\",\"type\":\"uint8[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasAmounts\",\"type\":\"uint256[]\"}],\"indexed\":false,\"internalType\":\"struct GlobalProposal.GlobalProposalDetail\",\"name\":\"globalProposal\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"}],\"name\":\"GlobalProposalCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"}],\"name\":\"ProposalApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"round\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"targets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasAmounts\",\"type\":\"uint256[]\"}],\"indexed\":false,\"internalType\":\"struct Proposal.ProposalDetail\",\"name\":\"proposal\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"}],\"name\":\"ProposalCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool[]\",\"name\":\"successCalls\",\"type\":\"bool[]\"},{\"indexed\":false,\"internalType\":\"bytes[]\",\"name\":\"returnDatas\",\"type\":\"bytes[]\"}],\"name\":\"ProposalExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"}],\"name\":\"ProposalExpired\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"}],\"name\":\"ProposalRejected\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enum Ballot.VoteType\",\"name\":\"support\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"name\":\"ProposalVoted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"RoninTrustedOrganizationContractUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridgeContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_period\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_voter\",\"type\":\"address\"}],\"name\":\"bridgeOperatorsVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"enum GlobalProposal.TargetOption[]\",\"name\":\"targetOptions\",\"type\":\"uint8[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasAmounts\",\"type\":\"uint256[]\"}],\"internalType\":\"struct GlobalProposal.GlobalProposalDetail\",\"name\":\"_globalProposal\",\"type\":\"tuple\"},{\"internalType\":\"enum Ballot.VoteType[]\",\"name\":\"_supports\",\"type\":\"uint8[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct SignatureConsumer.Signature[]\",\"name\":\"_signatures\",\"type\":\"tuple[]\"}],\"name\":\"castGlobalProposalBySignatures\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"targets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasAmounts\",\"type\":\"uint256[]\"}],\"internalType\":\"struct Proposal.ProposalDetail\",\"name\":\"_proposal\",\"type\":\"tuple\"},{\"internalType\":\"enum Ballot.VoteType[]\",\"name\":\"_supports\",\"type\":\"uint8[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct SignatureConsumer.Signature[]\",\"name\":\"_signatures\",\"type\":\"tuple[]\"}],\"name\":\"castProposalBySignatures\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"round\",\"type\":\"uint256\"}],\"name\":\"deleteExpired\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_period\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"_voters\",\"type\":\"address[]\"}],\"name\":\"getBridgeOperatorVotingSignatures\",\"outputs\":[{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct SignatureConsumer.Signature[]\",\"name\":\"_signatures\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getProposalExpiryDuration\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_round\",\"type\":\"uint256\"}],\"name\":\"getProposalSignatures\",\"outputs\":[{\"internalType\":\"enum Ballot.VoteType[]\",\"name\":\"_supports\",\"type\":\"uint8[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct SignatureConsumer.Signature[]\",\"name\":\"_signatures\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridgeVoter\",\"type\":\"address\"}],\"name\":\"lastVotedBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_round\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_voter\",\"type\":\"address\"}],\"name\":\"proposalVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"_targets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_gasAmounts\",\"type\":\"uint256[]\"}],\"name\":\"propose\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"enum GlobalProposal.TargetOption[]\",\"name\":\"_targetOptions\",\"type\":\"uint8[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_gasAmounts\",\"type\":\"uint256[]\"}],\"name\":\"proposeGlobal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"enum GlobalProposal.TargetOption[]\",\"name\":\"targetOptions\",\"type\":\"uint8[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasAmounts\",\"type\":\"uint256[]\"}],\"internalType\":\"struct GlobalProposal.GlobalProposalDetail\",\"name\":\"_globalProposal\",\"type\":\"tuple\"},{\"internalType\":\"enum Ballot.VoteType[]\",\"name\":\"_supports\",\"type\":\"uint8[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct SignatureConsumer.Signature[]\",\"name\":\"_signatures\",\"type\":\"tuple[]\"}],\"name\":\"proposeGlobalProposalStructAndCastVotes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"targets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasAmounts\",\"type\":\"uint256[]\"}],\"internalType\":\"struct Proposal.ProposalDetail\",\"name\":\"_proposal\",\"type\":\"tuple\"},{\"internalType\":\"enum Ballot.VoteType[]\",\"name\":\"_supports\",\"type\":\"uint8[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct SignatureConsumer.Signature[]\",\"name\":\"_signatures\",\"type\":\"tuple[]\"}],\"name\":\"proposeProposalStructAndCastVotes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"roninTrustedOrganizationContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"round\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"setBridgeContract\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_expiryDuration\",\"type\":\"uint256\"}],\"name\":\"setProposalExpiryDuration\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"setRoninTrustedOrganizationContract\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"vote\",\"outputs\":[{\"internalType\":\"enum VoteStatusConsumer.VoteStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"againstVoteWeight\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"forVoteWeight\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiryTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_period\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"_operators\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct SignatureConsumer.Signature[]\",\"name\":\"_signatures\",\"type\":\"tuple[]\"}],\"name\":\"voteBridgeOperatorsBySignatures\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"BridgeOperatorsApproved(uint256,address[])\":{\"details\":\"Emitted when the bridge operators are approved.\"}},\"kind\":\"dev\",\"methods\":{\"bridgeContract()\":{\"details\":\"Returns the bridge contract.\"},\"bridgeOperatorsVoted(uint256,address)\":{\"details\":\"Returns whether the voter `_voter` casted vote for bridge operators at a specific period.\"},\"castGlobalProposalBySignatures((uint256,uint256,uint8[],uint256[],bytes[],uint256[]),uint8[],(uint8,bytes32,bytes32)[])\":{\"details\":\"See `GovernanceProposal-_castGlobalProposalBySignatures`.\"},\"castProposalBySignatures((uint256,uint256,uint256,address[],uint256[],bytes[],uint256[]),uint8[],(uint8,bytes32,bytes32)[])\":{\"details\":\"See `GovernanceProposal-_castProposalBySignatures`.\"},\"changeProxyAdmin(address,address)\":{\"details\":\"Changes the admin of `_proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `_proxy`.\"},\"deleteExpired(uint256,uint256)\":{\"details\":\"See `CoreGovernance-_deleteExpiredProposal`\"},\"getBridgeOperatorVotingSignatures(uint256,address[])\":{\"details\":\"Returns the voted signatures for bridge operators at a specific period. Note: Does not verify whether the voter casted vote for the proposal and the returned signature can be empty. Please consider filtering for empty signatures after calling this function.\"},\"getProposalExpiryDuration()\":{\"details\":\"Returns the proposal expiry duration.\"},\"getProposalSignatures(uint256,uint256)\":{\"details\":\"Returns the voted signatures for the proposals.\"},\"getProxyAdmin(address)\":{\"details\":\"Returns the current admin of `_proxy`. Requirements: - This contract must be the admin of `_proxy`.\"},\"getProxyImplementation(address)\":{\"details\":\"Returns the current implementation of `_proxy`. Requirements: - This contract must be the admin of `_proxy`.\"},\"lastVotedBlock(address)\":{\"details\":\"Returns the last voted block of the bridge voter.\"},\"proposalVoted(uint256,uint256,address)\":{\"details\":\"Returns whether the voter `_voter` casted vote for the proposal.\"},\"propose(uint256,uint256,address[],uint256[],bytes[],uint256[])\":{\"details\":\"See `CoreGovernance-_proposeProposal`. Requirements: - The method caller is governor.\"},\"proposeGlobal(uint256,uint8[],uint256[],bytes[],uint256[])\":{\"details\":\"See `CoreGovernance-_proposeGlobal`. Requirements: - The method caller is governor.\"},\"proposeGlobalProposalStructAndCastVotes((uint256,uint256,uint8[],uint256[],bytes[],uint256[]),uint8[],(uint8,bytes32,bytes32)[])\":{\"details\":\"See `GovernanceProposal-_proposeGlobalProposalStructAndCastVotes`. Requirements: - The method caller is governor.\"},\"proposeProposalStructAndCastVotes((uint256,uint256,uint256,address[],uint256[],bytes[],uint256[]),uint8[],(uint8,bytes32,bytes32)[])\":{\"details\":\"See `GovernanceProposal-_proposeProposalStructAndCastVotes`. Requirements: - The method caller is governor.\"},\"roninTrustedOrganizationContract()\":{\"details\":\"Returns the ronin trusted organization contract.\"},\"setBridgeContract(address)\":{\"details\":\"Sets the bridge contract. Requirements: - The method caller is admin. - The new address is a contract. Emits the event `BridgeContractUpdated`.\"},\"setProposalExpiryDuration(uint256)\":{\"details\":\"Sets the expiry duration for a new proposal. Requirements: - Only allowing self-call to this method, since this contract does not have admin.\"},\"setRoninTrustedOrganizationContract(address)\":{\"details\":\"Sets the ronin trusted organization contract. Requirements: - The method caller is admin. - The new address is a contract. Emits the event `RoninTrustedOrganizationContractUpdated`.\"},\"voteBridgeOperatorsBySignatures(uint256,address[],(uint8,bytes32,bytes32)[])\":{\"details\":\"See `BOsGovernanceProposal-_castVotesBySignatures`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"round(uint256)\":{\"notice\":\"chain id = 0 for global proposal\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ronin/RoninGovernanceAdmin.sol\":\"RoninGovernanceAdmin\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xdb7f5c28fc61cda0bd8ab60ce288e206b791643bcd3ba464a70cbec18895a2f5\",\"license\":\"MIT\"},\"contracts/extensions/GovernanceAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"../extensions/sequential-governance/CoreGovernance.sol\\\";\\nimport \\\"../extensions/collections/HasRoninTrustedOrganizationContract.sol\\\";\\nimport \\\"../extensions/collections/HasBridgeContract.sol\\\";\\nimport \\\"../interfaces/IRoninTrustedOrganization.sol\\\";\\n\\nabstract contract GovernanceAdmin is CoreGovernance, HasRoninTrustedOrganizationContract, HasBridgeContract {\\n /// @dev Domain separator\\n bytes32 public constant DOMAIN_SEPARATOR = 0xf8704f8860d9e985bf6c52ec4738bd10fe31487599b36c0944f746ea09dc256b;\\n\\n modifier onlySelfCall() {\\n require(msg.sender == address(this), \\\"GovernanceAdmin: only allowed self-call\\\");\\n _;\\n }\\n\\n constructor(\\n address _roninTrustedOrganizationContract,\\n address _bridgeContract,\\n uint256 _proposalExpiryDuration\\n ) CoreGovernance(_proposalExpiryDuration) {\\n require(\\n keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,bytes32 salt)\\\"),\\n keccak256(\\\"GovernanceAdmin\\\"), // name hash\\n keccak256(\\\"1\\\"), // version hash\\n keccak256(abi.encode(\\\"RONIN_GOVERNANCE_ADMIN\\\", 2020)) // salt\\n )\\n ) == DOMAIN_SEPARATOR,\\n \\\"GovernanceAdmin: invalid domain\\\"\\n );\\n _setRoninTrustedOrganizationContract(_roninTrustedOrganizationContract);\\n _setBridgeContract(_bridgeContract);\\n }\\n\\n /**\\n * @inheritdoc IHasRoninTrustedOrganizationContract\\n */\\n function setRoninTrustedOrganizationContract(address _addr) external override onlySelfCall {\\n require(_addr.code.length > 0, \\\"GovernanceAdmin: set to non-contract\\\");\\n _setRoninTrustedOrganizationContract(_addr);\\n }\\n\\n /**\\n * @inheritdoc IHasBridgeContract\\n */\\n function setBridgeContract(address _addr) external override onlySelfCall {\\n require(_addr.code.length > 0, \\\"GovernanceAdmin: set to non-contract\\\");\\n _setBridgeContract(_addr);\\n }\\n\\n /**\\n * @dev Sets the expiry duration for a new proposal.\\n *\\n * Requirements:\\n * - Only allowing self-call to this method, since this contract does not have admin.\\n *\\n */\\n function setProposalExpiryDuration(uint256 _expiryDuration) external onlySelfCall {\\n _setProposalExpiryDuration(_expiryDuration);\\n }\\n\\n /**\\n * @dev Returns the current implementation of `_proxy`.\\n *\\n * Requirements:\\n * - This contract must be the admin of `_proxy`.\\n *\\n */\\n function getProxyImplementation(address _proxy) external view returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"implementation()\\\")) == 0x5c60da1b\\n (bool _success, bytes memory _returndata) = _proxy.staticcall(hex\\\"5c60da1b\\\");\\n require(_success, \\\"GovernanceAdmin: proxy call `implementation()` failed\\\");\\n return abi.decode(_returndata, (address));\\n }\\n\\n /**\\n * @dev Returns the proposal expiry duration.\\n */\\n function getProposalExpiryDuration() external view returns (uint256) {\\n return super._getProposalExpiryDuration();\\n }\\n\\n /**\\n * @dev Returns the current admin of `_proxy`.\\n *\\n * Requirements:\\n * - This contract must be the admin of `_proxy`.\\n *\\n */\\n function getProxyAdmin(address _proxy) external view returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"admin()\\\")) == 0xf851a440\\n (bool _success, bytes memory _returndata) = _proxy.staticcall(hex\\\"f851a440\\\");\\n require(_success, \\\"GovernanceAdmin: proxy call `admin()` failed\\\");\\n return abi.decode(_returndata, (address));\\n }\\n\\n /**\\n * @dev Changes the admin of `_proxy` to `newAdmin`.\\n *\\n * Requirements:\\n * - This contract must be the current admin of `_proxy`.\\n *\\n */\\n function changeProxyAdmin(address _proxy, address _newAdmin) external onlySelfCall {\\n // bytes4(keccak256(\\\"changeAdmin(address)\\\"))\\n (bool _success, ) = _proxy.call(abi.encodeWithSelector(0x8f283970, _newAdmin));\\n require(_success, \\\"GovernanceAdmin: proxy call `changeAdmin(address)` failed\\\");\\n }\\n\\n /**\\n * @dev Override `CoreGovernance-_getMinimumVoteWeight`.\\n */\\n function _getMinimumVoteWeight() internal view virtual override returns (uint256) {\\n (bool _success, bytes memory _returndata) = roninTrustedOrganizationContract().staticcall(\\n abi.encodeWithSelector(\\n // TransparentUpgradeableProxyV2.functionDelegateCall.selector,\\n 0x4bb5274a,\\n abi.encodeWithSelector(IQuorum.minimumVoteWeight.selector)\\n )\\n );\\n require(_success, \\\"GovernanceAdmin: proxy call `minimumVoteWeight()` failed\\\");\\n return abi.decode(_returndata, (uint256));\\n }\\n\\n /**\\n * @dev Override `CoreGovernance-_getTotalWeights`.\\n */\\n function _getTotalWeights() internal view virtual override returns (uint256) {\\n (bool _success, bytes memory _returndata) = roninTrustedOrganizationContract().staticcall(\\n abi.encodeWithSelector(\\n // TransparentUpgradeableProxyV2.functionDelegateCall.selector,\\n 0x4bb5274a,\\n abi.encodeWithSelector(IRoninTrustedOrganization.totalWeights.selector)\\n )\\n );\\n require(_success, \\\"GovernanceAdmin: proxy call `totalWeights()` failed\\\");\\n return abi.decode(_returndata, (uint256));\\n }\\n}\\n\",\"keccak256\":\"0x07e179dc68e1d5a860b2b0c9f50730307ec681e3a32c1e41bca5cdcda5e3da51\",\"license\":\"MIT\"},\"contracts/extensions/collections/HasBridgeContract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./HasProxyAdmin.sol\\\";\\nimport \\\"../../interfaces/collections/IHasBridgeContract.sol\\\";\\nimport \\\"../../interfaces/IBridge.sol\\\";\\n\\ncontract HasBridgeContract is IHasBridgeContract, HasProxyAdmin {\\n IBridge internal _bridgeContract;\\n\\n modifier onlyBridgeContract() {\\n require(bridgeContract() == msg.sender, \\\"HasBridgeContract: method caller must be bridge contract\\\");\\n _;\\n }\\n\\n /**\\n * @inheritdoc IHasBridgeContract\\n */\\n function bridgeContract() public view override returns (address) {\\n return address(_bridgeContract);\\n }\\n\\n /**\\n * @inheritdoc IHasBridgeContract\\n */\\n function setBridgeContract(address _addr) external virtual override onlyAdmin {\\n require(_addr.code.length > 0, \\\"HasBridgeContract: set to non-contract\\\");\\n _setBridgeContract(_addr);\\n }\\n\\n /**\\n * @dev Sets the bridge contract.\\n *\\n * Emits the event `BridgeContractUpdated`.\\n *\\n */\\n function _setBridgeContract(address _addr) internal {\\n _bridgeContract = IBridge(_addr);\\n emit BridgeContractUpdated(_addr);\\n }\\n}\\n\",\"keccak256\":\"0xf4dfa576336d50ab380c3310735575f8729cff0089813abb1a8506ad2cca0f00\",\"license\":\"MIT\"},\"contracts/extensions/collections/HasProxyAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/StorageSlot.sol\\\";\\n\\nabstract contract HasProxyAdmin {\\n // bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n modifier onlyAdmin() {\\n require(msg.sender == _getAdmin(), \\\"HasProxyAdmin: unauthorized sender\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns proxy admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n}\\n\",\"keccak256\":\"0x0c2fcf25290180e8cd733691b113464cdde671dc019e6c343e9eb3e16c6ca24a\",\"license\":\"MIT\"},\"contracts/extensions/collections/HasRoninTrustedOrganizationContract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./HasProxyAdmin.sol\\\";\\nimport \\\"../../interfaces/collections/IHasRoninTrustedOrganizationContract.sol\\\";\\nimport \\\"../../interfaces/IRoninTrustedOrganization.sol\\\";\\n\\ncontract HasRoninTrustedOrganizationContract is IHasRoninTrustedOrganizationContract, HasProxyAdmin {\\n IRoninTrustedOrganization internal _roninTrustedOrganizationContract;\\n\\n modifier onlyRoninTrustedOrganizationContract() {\\n require(\\n roninTrustedOrganizationContract() == msg.sender,\\n \\\"HasRoninTrustedOrganizationContract: method caller must be ronin trusted organization contract\\\"\\n );\\n _;\\n }\\n\\n /**\\n * @inheritdoc IHasRoninTrustedOrganizationContract\\n */\\n function roninTrustedOrganizationContract() public view override returns (address) {\\n return address(_roninTrustedOrganizationContract);\\n }\\n\\n /**\\n * @inheritdoc IHasRoninTrustedOrganizationContract\\n */\\n function setRoninTrustedOrganizationContract(address _addr) external virtual override onlyAdmin {\\n require(_addr.code.length > 0, \\\"HasRoninTrustedOrganizationContract: set to non-contract\\\");\\n _setRoninTrustedOrganizationContract(_addr);\\n }\\n\\n /**\\n * @dev Sets the ronin trusted organization contract.\\n *\\n * Emits the event `RoninTrustedOrganizationContractUpdated`.\\n *\\n */\\n function _setRoninTrustedOrganizationContract(address _addr) internal {\\n _roninTrustedOrganizationContract = IRoninTrustedOrganization(_addr);\\n emit RoninTrustedOrganizationContractUpdated(_addr);\\n }\\n}\\n\",\"keccak256\":\"0xbdfbd30aa984f10f191b21e4b790ff1872445c7387cf359aadd863aac6635507\",\"license\":\"MIT\"},\"contracts/extensions/isolated-governance/IsolatedGovernance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport \\\"../../interfaces/consumers/VoteStatusConsumer.sol\\\";\\n\\nabstract contract IsolatedGovernance is VoteStatusConsumer {\\n struct IsolatedVote {\\n VoteStatus status;\\n bytes32 finalHash;\\n /// @dev Mapping from voter => receipt hash\\n mapping(address => bytes32) voteHashOf;\\n /// @dev Mapping from receipt hash => vote weight\\n mapping(bytes32 => uint256) weight;\\n }\\n\\n /**\\n * @dev Casts vote for the receipt with the receipt hash `_hash`.\\n *\\n * Requirements:\\n * - The vote is not finalized.\\n * - The voter has not voted for the round.\\n *\\n */\\n function _castVote(\\n IsolatedVote storage _proposal,\\n address _voter,\\n uint256 _voterWeight,\\n uint256 _minimumVoteWeight,\\n bytes32 _hash\\n ) internal virtual returns (VoteStatus _status) {\\n if (_voted(_proposal, _voter)) {\\n revert(\\n string(abi.encodePacked(\\\"IsolatedGovernance: \\\", Strings.toHexString(uint160(_voter), 20), \\\" already voted\\\"))\\n );\\n }\\n\\n // Record for voter\\n _proposal.voteHashOf[_voter] = _hash;\\n // Increase vote weight\\n uint256 _weight = _proposal.weight[_hash] += _voterWeight;\\n\\n if (_weight >= _minimumVoteWeight && _proposal.status == VoteStatus.Pending) {\\n _proposal.status = VoteStatus.Approved;\\n _proposal.finalHash = _hash;\\n }\\n\\n _status = _proposal.status;\\n }\\n\\n /**\\n * @dev Returns whether the voter casted for the proposal.\\n */\\n function _voted(IsolatedVote storage _proposal, address _voter) internal view virtual returns (bool) {\\n return _proposal.voteHashOf[_voter] != bytes32(0);\\n }\\n}\\n\",\"keccak256\":\"0x0c84a1e18e5472ec179c0ccba6de642ad53e26a908f66f7fedc1f85499e2513c\",\"license\":\"MIT\"},\"contracts/extensions/isolated-governance/bridge-operator-governance/BOsGovernanceProposal.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../../extensions/isolated-governance/IsolatedGovernance.sol\\\";\\nimport \\\"../../../interfaces/consumers/SignatureConsumer.sol\\\";\\nimport \\\"../../../libraries/BridgeOperatorsBallot.sol\\\";\\nimport \\\"../../../interfaces/IRoninGovernanceAdmin.sol\\\";\\n\\nabstract contract BOsGovernanceProposal is SignatureConsumer, IsolatedGovernance, IRoninGovernanceAdmin {\\n /// @dev The last period that the brige operators synced.\\n uint256 internal _lastSyncedPeriod;\\n /// @dev Mapping from period index => bridge operators vote\\n mapping(uint256 => IsolatedVote) internal _vote;\\n\\n /// @dev Mapping from bridge voter address => last block that the address voted\\n mapping(address => uint256) internal _lastVotedBlock;\\n /// @dev Mapping from period => voter => signatures\\n mapping(uint256 => mapping(address => Signature)) internal _votingSig;\\n\\n /**\\n * @inheritdoc IRoninGovernanceAdmin\\n */\\n function lastVotedBlock(address _bridgeVoter) external view returns (uint256) {\\n return _lastVotedBlock[_bridgeVoter];\\n }\\n\\n /**\\n * @dev Votes for a set of bridge operators by signatures.\\n *\\n * Requirements:\\n * - The period of voting is larger than the last synced period.\\n * - The arrays are not empty.\\n * - The signature signers are in order.\\n *\\n */\\n function _castVotesBySignatures(\\n address[] calldata _operators,\\n Signature[] calldata _signatures,\\n uint256 _period,\\n uint256 _minimumVoteWeight,\\n bytes32 _domainSeperator\\n ) internal {\\n require(_period >= _lastSyncedPeriod, \\\"BOsGovernanceProposal: query for outdated period\\\");\\n require(_operators.length > 0 && _signatures.length > 0, \\\"BOsGovernanceProposal: invalid array length\\\");\\n\\n Signature memory _sig;\\n address _signer;\\n address _lastSigner;\\n bytes32 _hash = BridgeOperatorsBallot.hash(_period, _operators);\\n bytes32 _digest = ECDSA.toTypedDataHash(_domainSeperator, _hash);\\n IsolatedVote storage _v = _vote[_period];\\n bool _hasValidVotes;\\n\\n for (uint256 _i = 0; _i < _signatures.length; _i++) {\\n _sig = _signatures[_i];\\n _signer = ECDSA.recover(_digest, _sig.v, _sig.r, _sig.s);\\n require(_lastSigner < _signer, \\\"BOsGovernanceProposal: invalid order\\\");\\n _lastSigner = _signer;\\n\\n uint256 _weight = _getBridgeVoterWeight(_signer);\\n if (_weight > 0) {\\n _hasValidVotes = true;\\n _lastVotedBlock[_signer] = block.number;\\n _votingSig[_period][_signer] = _sig;\\n if (_castVote(_v, _signer, _weight, _minimumVoteWeight, _hash) == VoteStatus.Approved) {\\n return;\\n }\\n }\\n }\\n\\n require(_hasValidVotes, \\\"BOsGovernanceProposal: invalid signatures\\\");\\n }\\n\\n /**\\n * @dev Returns the weight of a bridge voter.\\n */\\n function _getBridgeVoterWeight(address _bridgeVoter) internal view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xdaeae7aa91963ce5160cce59482eb1366a6d85692deaf7504a4b18735ff2cfd2\",\"license\":\"MIT\"},\"contracts/extensions/sequential-governance/CoreGovernance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport \\\"../../libraries/Proposal.sol\\\";\\nimport \\\"../../libraries/GlobalProposal.sol\\\";\\nimport \\\"../../libraries/Ballot.sol\\\";\\nimport \\\"../../interfaces/consumers/ChainTypeConsumer.sol\\\";\\nimport \\\"../../interfaces/consumers/SignatureConsumer.sol\\\";\\nimport \\\"../../interfaces/consumers/VoteStatusConsumer.sol\\\";\\n\\nabstract contract CoreGovernance is SignatureConsumer, VoteStatusConsumer, ChainTypeConsumer {\\n using Proposal for Proposal.ProposalDetail;\\n using GlobalProposal for GlobalProposal.GlobalProposalDetail;\\n\\n struct ProposalVote {\\n VoteStatus status;\\n bytes32 hash;\\n uint256 againstVoteWeight; // Total weight of against votes\\n uint256 forVoteWeight; // Total weight of for votes\\n address[] forVoteds; // Array of addresses voting for\\n address[] againstVoteds; // Array of addresses voting against\\n uint256 expiryTimestamp;\\n mapping(address => Signature) sig;\\n }\\n\\n /// @dev Emitted when a proposal is created\\n event ProposalCreated(\\n uint256 indexed chainId,\\n uint256 indexed round,\\n bytes32 indexed proposalHash,\\n Proposal.ProposalDetail proposal,\\n address creator\\n );\\n /// @dev Emitted when a proposal is created\\n event GlobalProposalCreated(\\n uint256 indexed round,\\n bytes32 indexed proposalHash,\\n Proposal.ProposalDetail proposal,\\n bytes32 globalProposalHash,\\n GlobalProposal.GlobalProposalDetail globalProposal,\\n address creator\\n );\\n /// @dev Emitted when the proposal is voted\\n event ProposalVoted(bytes32 indexed proposalHash, address indexed voter, Ballot.VoteType support, uint256 weight);\\n /// @dev Emitted when the proposal is approved\\n event ProposalApproved(bytes32 indexed proposalHash);\\n /// @dev Emitted when the vote is reject\\n event ProposalRejected(bytes32 indexed proposalHash);\\n /// @dev Emitted when the vote is expired\\n event ProposalExpired(bytes32 indexed proposalHash);\\n /// @dev Emitted when the proposal is executed\\n event ProposalExecuted(bytes32 indexed proposalHash, bool[] successCalls, bytes[] returnDatas);\\n\\n /// @dev Mapping from chain id => vote round\\n /// @notice chain id = 0 for global proposal\\n mapping(uint256 => uint256) public round;\\n /// @dev Mapping from chain id => vote round => proposal vote\\n mapping(uint256 => mapping(uint256 => ProposalVote)) public vote;\\n\\n uint256 private _proposalExpiryDuration;\\n\\n constructor(uint256 _expiryDuration) {\\n _setProposalExpiryDuration(_expiryDuration);\\n }\\n\\n /**\\n * @dev Creates new round voting for the proposal `_proposalHash` of chain `_chainId`.\\n */\\n function _createVotingRound(\\n uint256 _chainId,\\n bytes32 _proposalHash,\\n uint256 _expiryTimestamp\\n ) internal returns (uint256 _round) {\\n _round = round[_chainId];\\n\\n // Skip checking for the first ever round\\n if (_round == 0) {\\n _round = round[_chainId] = 1;\\n } else {\\n ProposalVote storage _latestProposalVote = vote[_chainId][_round];\\n bool _isExpired = _tryDeleteExpiredVotingRound(_latestProposalVote);\\n // Skip increase round number if the latest round is expired, allow the vote to be overridden\\n if (!_isExpired) {\\n require(_latestProposalVote.status != VoteStatus.Pending, \\\"CoreGovernance: current proposal is not completed\\\");\\n _round = ++round[_chainId];\\n }\\n }\\n\\n vote[_chainId][_round].hash = _proposalHash;\\n vote[_chainId][_round].expiryTimestamp = _expiryTimestamp;\\n }\\n\\n /**\\n * @dev Proposes for a new proposal.\\n *\\n * Requirements:\\n * - The chain id is not equal to 0.\\n *\\n * Emits the `ProposalCreated` event.\\n *\\n */\\n function _proposeProposal(\\n uint256 _chainId,\\n uint256 _expiryTimestamp,\\n address[] memory _targets,\\n uint256[] memory _values,\\n bytes[] memory _calldatas,\\n uint256[] memory _gasAmounts,\\n address _creator\\n ) internal virtual returns (uint256 _round) {\\n require(_chainId != 0, \\\"CoreGovernance: invalid chain id\\\");\\n\\n Proposal.ProposalDetail memory _proposal = Proposal.ProposalDetail(\\n round[_chainId] + 1,\\n _chainId,\\n _expiryTimestamp,\\n _targets,\\n _values,\\n _calldatas,\\n _gasAmounts\\n );\\n _proposal.validate(_proposalExpiryDuration);\\n\\n bytes32 _proposalHash = _proposal.hash();\\n _round = _createVotingRound(_chainId, _proposalHash, _expiryTimestamp);\\n emit ProposalCreated(_chainId, _round, _proposalHash, _proposal, _creator);\\n }\\n\\n /**\\n * @dev Proposes proposal struct.\\n *\\n * Requirements:\\n * - The chain id is not equal to 0.\\n * - The proposal nonce is equal to the new round.\\n *\\n * Emits the `ProposalCreated` event.\\n *\\n */\\n function _proposeProposalStruct(Proposal.ProposalDetail memory _proposal, address _creator)\\n internal\\n virtual\\n returns (uint256 _round)\\n {\\n uint256 _chainId = _proposal.chainId;\\n require(_chainId != 0, \\\"CoreGovernance: invalid chain id\\\");\\n _proposal.validate(_proposalExpiryDuration);\\n\\n bytes32 _proposalHash = _proposal.hash();\\n _round = _createVotingRound(_chainId, _proposalHash, _proposal.expiryTimestamp);\\n require(_round == _proposal.nonce, \\\"CoreGovernance: invalid proposal nonce\\\");\\n emit ProposalCreated(_chainId, _round, _proposalHash, _proposal, _creator);\\n }\\n\\n /**\\n * @dev Proposes for a global proposal.\\n *\\n * Emits the `GlobalProposalCreated` event.\\n *\\n */\\n function _proposeGlobal(\\n uint256 _expiryTimestamp,\\n GlobalProposal.TargetOption[] calldata _targetOptions,\\n uint256[] memory _values,\\n bytes[] memory _calldatas,\\n uint256[] memory _gasAmounts,\\n address _roninTrustedOrganizationContract,\\n address _gatewayContract,\\n address _creator\\n ) internal virtual returns (uint256 _round) {\\n GlobalProposal.GlobalProposalDetail memory _globalProposal = GlobalProposal.GlobalProposalDetail(\\n round[0] + 1,\\n _expiryTimestamp,\\n _targetOptions,\\n _values,\\n _calldatas,\\n _gasAmounts\\n );\\n Proposal.ProposalDetail memory _proposal = _globalProposal.into_proposal_detail(\\n _roninTrustedOrganizationContract,\\n _gatewayContract\\n );\\n _proposal.validate(_proposalExpiryDuration);\\n\\n bytes32 _proposalHash = _proposal.hash();\\n _round = _createVotingRound(0, _proposalHash, _expiryTimestamp);\\n emit GlobalProposalCreated(_round, _proposalHash, _proposal, _globalProposal.hash(), _globalProposal, _creator);\\n }\\n\\n /**\\n * @dev Proposes global proposal struct.\\n *\\n * Requirements:\\n * - The proposal nonce is equal to the new round.\\n *\\n * Emits the `GlobalProposalCreated` event.\\n *\\n */\\n function _proposeGlobalStruct(\\n GlobalProposal.GlobalProposalDetail memory _globalProposal,\\n address _roninTrustedOrganizationContract,\\n address _gatewayContract,\\n address _creator\\n ) internal virtual returns (Proposal.ProposalDetail memory _proposal, uint256 _round) {\\n _proposal = _globalProposal.into_proposal_detail(_roninTrustedOrganizationContract, _gatewayContract);\\n _proposal.validate(_proposalExpiryDuration);\\n\\n bytes32 _proposalHash = _proposal.hash();\\n _round = _createVotingRound(0, _proposalHash, _globalProposal.expiryTimestamp);\\n require(_round == _proposal.nonce, \\\"CoreGovernance: invalid proposal nonce\\\");\\n emit GlobalProposalCreated(_round, _proposalHash, _proposal, _globalProposal.hash(), _globalProposal, _creator);\\n }\\n\\n /**\\n * @dev Casts vote for the proposal with data and returns whether the voting is done.\\n *\\n * Requirements:\\n * - The proposal nonce is equal to the round.\\n * - The vote is not finalized.\\n * - The voter has not voted for the round.\\n *\\n * Emits the `ProposalVoted` event. Emits the `ProposalApproved`, `ProposalExecuted` or `ProposalRejected` once the\\n * proposal is approved, executed or rejected.\\n *\\n */\\n function _castVote(\\n Proposal.ProposalDetail memory _proposal,\\n Ballot.VoteType _support,\\n uint256 _minimumForVoteWeight,\\n uint256 _minimumAgainstVoteWeight,\\n address _voter,\\n Signature memory _signature,\\n uint256 _voterWeight\\n ) internal virtual returns (bool _done) {\\n uint256 _chainId = _proposal.chainId;\\n uint256 _round = _proposal.nonce;\\n ProposalVote storage _vote = vote[_chainId][_round];\\n\\n if (_tryDeleteExpiredVotingRound(_vote)) {\\n return true;\\n }\\n\\n require(round[_proposal.chainId] == _round, \\\"CoreGovernance: query for invalid proposal nonce\\\");\\n require(_vote.status == VoteStatus.Pending, \\\"CoreGovernance: the vote is finalized\\\");\\n if (_voted(_vote, _voter)) {\\n revert(string(abi.encodePacked(\\\"CoreGovernance: \\\", Strings.toHexString(uint160(_voter), 20), \\\" already voted\\\")));\\n }\\n\\n _vote.sig[_voter] = _signature;\\n emit ProposalVoted(_vote.hash, _voter, _support, _voterWeight);\\n\\n uint256 _forVoteWeight;\\n uint256 _againstVoteWeight;\\n if (_support == Ballot.VoteType.For) {\\n _vote.forVoteds.push(_voter);\\n _forVoteWeight = _vote.forVoteWeight += _voterWeight;\\n } else if (_support == Ballot.VoteType.Against) {\\n _vote.againstVoteds.push(_voter);\\n _againstVoteWeight = _vote.againstVoteWeight += _voterWeight;\\n } else {\\n revert(\\\"CoreGovernance: unsupported vote type\\\");\\n }\\n\\n if (_forVoteWeight >= _minimumForVoteWeight) {\\n _done = true;\\n _vote.status = VoteStatus.Approved;\\n emit ProposalApproved(_vote.hash);\\n _tryExecute(_vote, _proposal);\\n } else if (_againstVoteWeight >= _minimumAgainstVoteWeight) {\\n _done = true;\\n _vote.status = VoteStatus.Rejected;\\n emit ProposalRejected(_vote.hash);\\n }\\n }\\n\\n /**\\n * @dev Delete the expired proposal by its chainId and nonce, without creating a new proposal.\\n */\\n function _deleteExpiredVotingRound(uint256 _chainId, uint256 _round) internal {\\n ProposalVote storage _vote = vote[_chainId][_round];\\n _tryDeleteExpiredVotingRound(_vote);\\n }\\n\\n /**\\n * @dev When the contract is on Ronin chain, checks whether the proposal is expired and delete it if is expired.\\n */\\n function _tryDeleteExpiredVotingRound(ProposalVote storage _proposalVote) private returns (bool _isExpired) {\\n _isExpired = _getChainType() == ChainType.RoninChain && _proposalVote.expiryTimestamp <= block.timestamp;\\n\\n if (_isExpired) {\\n emit ProposalExpired(_proposalVote.hash);\\n\\n for (uint256 _i; _i < _proposalVote.forVoteds.length; _i++) {\\n delete _proposalVote.sig[_proposalVote.forVoteds[_i]];\\n }\\n for (uint256 _i; _i < _proposalVote.againstVoteds.length; _i++) {\\n delete _proposalVote.sig[_proposalVote.againstVoteds[_i]];\\n }\\n delete _proposalVote.status;\\n delete _proposalVote.hash;\\n delete _proposalVote.againstVoteWeight;\\n delete _proposalVote.forVoteWeight;\\n delete _proposalVote.forVoteds;\\n delete _proposalVote.againstVoteds;\\n delete _proposalVote.expiryTimestamp;\\n }\\n }\\n\\n /**\\n * @dev Executes the proposal and update the vote status once the proposal is executable.\\n */\\n function _tryExecute(ProposalVote storage _vote, Proposal.ProposalDetail memory _proposal) internal {\\n if (_proposal.executable()) {\\n _vote.status = VoteStatus.Executed;\\n (bool[] memory _successCalls, bytes[] memory _returnDatas) = _proposal.execute();\\n emit ProposalExecuted(_vote.hash, _successCalls, _returnDatas);\\n }\\n }\\n\\n /**\\n * @dev Sets the expiry duration for a new proposal.\\n */\\n function _setProposalExpiryDuration(uint256 _expiryDuration) internal {\\n _proposalExpiryDuration = _expiryDuration;\\n }\\n\\n /**\\n * @dev Returns whether the voter casted for the proposal.\\n */\\n function _voted(ProposalVote storage _vote, address _voter) internal view returns (bool) {\\n return _vote.sig[_voter].r != 0;\\n }\\n\\n /**\\n * @dev Returns the expiry duration for a new proposal.\\n */\\n function _getProposalExpiryDuration() internal view returns (uint256) {\\n return _proposalExpiryDuration;\\n }\\n\\n /**\\n * @dev Returns total weight from validators.\\n */\\n function _getTotalWeights() internal view virtual returns (uint256);\\n\\n /**\\n * @dev Returns minimum vote to pass a proposal.\\n */\\n function _getMinimumVoteWeight() internal view virtual returns (uint256);\\n\\n /**\\n * @dev Returns current context is running on whether Ronin chain or on mainchain.\\n */\\n function _getChainType() internal view virtual returns (ChainType);\\n}\\n\",\"keccak256\":\"0x1482e3b25beb0e0ff4143ac264fbda361ba91f58f563e570e4e72b87bdb81a11\",\"license\":\"MIT\"},\"contracts/extensions/sequential-governance/GovernanceProposal.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./CoreGovernance.sol\\\";\\n\\nabstract contract GovernanceProposal is CoreGovernance {\\n using Proposal for Proposal.ProposalDetail;\\n using GlobalProposal for GlobalProposal.GlobalProposalDetail;\\n\\n /**\\n * @dev Casts votes by signatures.\\n *\\n * Note: This method does not verify the proposal hash with the vote hash. Please consider checking it before.\\n *\\n */\\n function _castVotesBySignatures(\\n Proposal.ProposalDetail memory _proposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures,\\n bytes32 _forDigest,\\n bytes32 _againstDigest\\n ) internal {\\n require(_supports.length > 0 && _supports.length == _signatures.length, \\\"GovernanceProposal: invalid array length\\\");\\n uint256 _minimumForVoteWeight = _getMinimumVoteWeight();\\n uint256 _minimumAgainstVoteWeight = _getTotalWeights() - _minimumForVoteWeight + 1;\\n\\n address _lastSigner;\\n address _signer;\\n Signature memory _sig;\\n bool _hasValidVotes;\\n for (uint256 _i; _i < _signatures.length; _i++) {\\n _sig = _signatures[_i];\\n\\n if (_supports[_i] == Ballot.VoteType.For) {\\n _signer = ECDSA.recover(_forDigest, _sig.v, _sig.r, _sig.s);\\n } else if (_supports[_i] == Ballot.VoteType.Against) {\\n _signer = ECDSA.recover(_againstDigest, _sig.v, _sig.r, _sig.s);\\n } else {\\n revert(\\\"GovernanceProposal: query for unsupported vote type\\\");\\n }\\n\\n require(_lastSigner < _signer, \\\"GovernanceProposal: invalid order\\\");\\n _lastSigner = _signer;\\n\\n uint256 _weight = _getWeight(_signer);\\n if (_weight > 0) {\\n _hasValidVotes = true;\\n if (\\n _castVote(_proposal, _supports[_i], _minimumForVoteWeight, _minimumAgainstVoteWeight, _signer, _sig, _weight)\\n ) {\\n return;\\n }\\n }\\n }\\n\\n require(_hasValidVotes, \\\"GovernanceProposal: invalid signatures\\\");\\n }\\n\\n /**\\n * @dev Proposes a proposal struct and casts votes by signature.\\n */\\n function _proposeProposalStructAndCastVotes(\\n Proposal.ProposalDetail calldata _proposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures,\\n bytes32 _domainSeparator,\\n address _creator\\n ) internal {\\n _proposeProposalStruct(_proposal, _creator);\\n bytes32 _proposalHash = _proposal.hash();\\n _castVotesBySignatures(\\n _proposal,\\n _supports,\\n _signatures,\\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_proposalHash, Ballot.VoteType.For)),\\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_proposalHash, Ballot.VoteType.Against))\\n );\\n }\\n\\n /**\\n * @dev Proposes a proposal struct and casts votes by signature.\\n */\\n function _castProposalBySignatures(\\n Proposal.ProposalDetail calldata _proposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures,\\n bytes32 _domainSeparator\\n ) internal {\\n bytes32 _proposalHash = _proposal.hash();\\n require(\\n vote[_proposal.chainId][_proposal.nonce].hash == _proposalHash,\\n \\\"GovernanceAdmin: cast vote for invalid proposal\\\"\\n );\\n _castVotesBySignatures(\\n _proposal,\\n _supports,\\n _signatures,\\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_proposalHash, Ballot.VoteType.For)),\\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_proposalHash, Ballot.VoteType.Against))\\n );\\n }\\n\\n /**\\n * @dev Proposes and votes by signature.\\n */\\n function _proposeGlobalProposalStructAndCastVotes(\\n GlobalProposal.GlobalProposalDetail calldata _globalProposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures,\\n bytes32 _domainSeparator,\\n address _roninTrustedOrganizationContract,\\n address _gatewayContract,\\n address _creator\\n ) internal returns (Proposal.ProposalDetail memory _proposal) {\\n (_proposal, ) = _proposeGlobalStruct(\\n _globalProposal,\\n _roninTrustedOrganizationContract,\\n _gatewayContract,\\n _creator\\n );\\n bytes32 _globalProposalHash = _globalProposal.hash();\\n _castVotesBySignatures(\\n _proposal,\\n _supports,\\n _signatures,\\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_globalProposalHash, Ballot.VoteType.For)),\\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_globalProposalHash, Ballot.VoteType.Against))\\n );\\n }\\n\\n /**\\n * @dev Proposes a global proposal struct and casts votes by signature.\\n */\\n function _castGlobalProposalBySignatures(\\n GlobalProposal.GlobalProposalDetail calldata _globalProposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures,\\n bytes32 _domainSeparator,\\n address _roninTrustedOrganizationContract,\\n address _gatewayContract\\n ) internal {\\n Proposal.ProposalDetail memory _proposal = _globalProposal.into_proposal_detail(\\n _roninTrustedOrganizationContract,\\n _gatewayContract\\n );\\n bytes32 _globalProposalHash = _globalProposal.hash();\\n require(vote[0][_proposal.nonce].hash == _proposal.hash(), \\\"GovernanceAdmin: cast vote for invalid proposal\\\");\\n _castVotesBySignatures(\\n _proposal,\\n _supports,\\n _signatures,\\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_globalProposalHash, Ballot.VoteType.For)),\\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_globalProposalHash, Ballot.VoteType.Against))\\n );\\n }\\n\\n /**\\n * @dev Returns the weight of a governor.\\n */\\n function _getWeight(address _governor) internal view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xe75f250d5c7da8b2c8892b417ba0bc7e14542718802c00f4df556a663d8f6ae7\",\"license\":\"MIT\"},\"contracts/interfaces/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IBridge {\\n /**\\n * @dev Replaces the old bridge operator list by the new one.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n *\\n * Emitted the event `BridgeOperatorsReplaced`.\\n *\\n */\\n function replaceBridgeOperators(address[] calldata) external;\\n\\n /**\\n * @dev Returns the bridge operator list.\\n */\\n function getBridgeOperators() external view returns (address[] memory);\\n}\\n\",\"keccak256\":\"0x614db701e54383b7d0a749bc9b0d2da95d42652cd673499bf71e25096548b96e\",\"license\":\"MIT\"},\"contracts/interfaces/IQuorum.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IQuorum {\\n /// @dev Emitted when the threshold is updated\\n event ThresholdUpdated(\\n uint256 indexed nonce,\\n uint256 indexed numerator,\\n uint256 indexed denominator,\\n uint256 previousNumerator,\\n uint256 previousDenominator\\n );\\n\\n /**\\n * @dev Returns the threshold.\\n */\\n function getThreshold() external view returns (uint256 _num, uint256 _denom);\\n\\n /**\\n * @dev Checks whether the `_voteWeight` passes the threshold.\\n */\\n function checkThreshold(uint256 _voteWeight) external view returns (bool);\\n\\n /**\\n * @dev Returns the minimum vote weight to pass the threshold.\\n */\\n function minimumVoteWeight() external view returns (uint256);\\n\\n /**\\n * @dev Sets the threshold.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n *\\n * Emits the `ThresholdUpdated` event.\\n *\\n */\\n function setThreshold(uint256 _numerator, uint256 _denominator)\\n external\\n returns (uint256 _previousNum, uint256 _previousDenom);\\n}\\n\",\"keccak256\":\"0x10f3b360430e6d03773c9959f54cbed6fb0346069645c05b05ef50cfb19f3753\",\"license\":\"MIT\"},\"contracts/interfaces/IRoninGovernanceAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IRoninGovernanceAdmin {\\n /**\\n * @dev Returns the last voted block of the bridge voter.\\n */\\n function lastVotedBlock(address _bridgeVoter) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0xaf8bbda9f65a09444b3ebbcd19a62e39bf8711047224744f86439db6f42551b2\",\"license\":\"MIT\"},\"contracts/interfaces/IRoninTrustedOrganization.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"./IQuorum.sol\\\";\\n\\ninterface IRoninTrustedOrganization is IQuorum {\\n struct TrustedOrganization {\\n // Address of the validator that produces block, e.g. block.coinbase. This is so-called validator address.\\n address consensusAddr;\\n // Address to voting proposal\\n address governor;\\n // Address to voting bridge operators\\n address bridgeVoter;\\n // Its Weight\\n uint256 weight;\\n // The block that the organization was added\\n uint256 addedBlock;\\n }\\n\\n /// @dev Emitted when the trusted organization is added.\\n event TrustedOrganizationsAdded(TrustedOrganization[] orgs);\\n /// @dev Emitted when the trusted organization is updated.\\n event TrustedOrganizationsUpdated(TrustedOrganization[] orgs);\\n /// @dev Emitted when the trusted organization is removed.\\n event TrustedOrganizationsRemoved(address[] orgs);\\n\\n /**\\n * @dev Adds a list of addresses into the trusted organization.\\n *\\n * Requirements:\\n * - The weights should larger than 0.\\n * - The method caller is admin.\\n * - The field `addedBlock` should be blank.\\n *\\n * Emits the event `TrustedOrganizationAdded` once an organization is added.\\n *\\n */\\n function addTrustedOrganizations(TrustedOrganization[] calldata) external;\\n\\n /**\\n * @dev Updates weights for a list of existent trusted organization.\\n *\\n * Requirements:\\n * - The weights should larger than 0.\\n * - The method caller is admin.\\n *\\n * Emits the `TrustedOrganizationUpdated` event.\\n *\\n */\\n function updateTrustedOrganizations(TrustedOrganization[] calldata _list) external;\\n\\n /**\\n * @dev Removes a list of addresses from the trusted organization.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n *\\n * Emits the event `TrustedOrganizationRemoved` once an organization is removed.\\n *\\n * @param _consensusAddrs The list of consensus addresses linked to corresponding trusted organization that to be removed.\\n */\\n function removeTrustedOrganizations(address[] calldata _consensusAddrs) external;\\n\\n /**\\n * @dev Returns total weights.\\n */\\n function totalWeights() external view returns (uint256);\\n\\n /**\\n * @dev Returns the weight of a consensus.\\n */\\n function getConsensusWeight(address _consensusAddr) external view returns (uint256);\\n\\n /**\\n * @dev Returns the weight of a governor.\\n */\\n function getGovernorWeight(address _governor) external view returns (uint256);\\n\\n /**\\n * @dev Returns the weight of a bridge voter.\\n */\\n function getBridgeVoterWeight(address _addr) external view returns (uint256);\\n\\n /**\\n * @dev Returns the weights of a list of consensus addresses.\\n */\\n function getConsensusWeights(address[] calldata _list) external view returns (uint256[] memory);\\n\\n /**\\n * @dev Returns the weights of a list of governor addresses.\\n */\\n function getGovernorWeights(address[] calldata _list) external view returns (uint256[] memory);\\n\\n /**\\n * @dev Returns the weights of a list of bridge voter addresses.\\n */\\n function getBridgeVoterWeights(address[] calldata _list) external view returns (uint256[] memory);\\n\\n /**\\n * @dev Returns total weights of the consensus list.\\n */\\n function sumConsensusWeights(address[] calldata _list) external view returns (uint256 _res);\\n\\n /**\\n * @dev Returns total weights of the governor list.\\n */\\n function sumGovernorWeights(address[] calldata _list) external view returns (uint256 _res);\\n\\n /**\\n * @dev Returns total weights of the bridge voter list.\\n */\\n function sumBridgeVoterWeights(address[] calldata _list) external view returns (uint256 _res);\\n\\n /**\\n * @dev Returns the trusted organization at `_index`.\\n */\\n function getTrustedOrganizationAt(uint256 _index) external view returns (TrustedOrganization memory);\\n\\n /**\\n * @dev Returns the number of trusted organizations.\\n */\\n function countTrustedOrganizations() external view returns (uint256);\\n\\n /**\\n * @dev Returns all of the trusted organizations.\\n */\\n function getAllTrustedOrganizations() external view returns (TrustedOrganization[] memory);\\n\\n /**\\n * @dev Returns the trusted organization by consensus address.\\n *\\n * Reverts once the consensus address is non-existent.\\n */\\n function getTrustedOrganization(address _consensusAddr) external view returns (TrustedOrganization memory);\\n}\\n\",\"keccak256\":\"0x1edb7a3f5d340e7efc141cb8d94c5499954dec869f026d3998ad92cbc714d604\",\"license\":\"MIT\"},\"contracts/interfaces/collections/IHasBridgeContract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface IHasBridgeContract {\\n /// @dev Emitted when the bridge contract is updated.\\n event BridgeContractUpdated(address);\\n\\n /**\\n * @dev Returns the bridge contract.\\n */\\n function bridgeContract() external view returns (address);\\n\\n /**\\n * @dev Sets the bridge contract.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n * - The new address is a contract.\\n *\\n * Emits the event `BridgeContractUpdated`.\\n *\\n */\\n function setBridgeContract(address) external;\\n}\\n\",\"keccak256\":\"0xb1c239a3987c93db20b65bb80f165861bc83a186fb8d5a1c17c5ad06cfb395a8\",\"license\":\"MIT\"},\"contracts/interfaces/collections/IHasRoninTrustedOrganizationContract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface IHasRoninTrustedOrganizationContract {\\n /// @dev Emitted when the ronin trusted organization contract is updated.\\n event RoninTrustedOrganizationContractUpdated(address);\\n\\n /**\\n * @dev Returns the ronin trusted organization contract.\\n */\\n function roninTrustedOrganizationContract() external view returns (address);\\n\\n /**\\n * @dev Sets the ronin trusted organization contract.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n * - The new address is a contract.\\n *\\n * Emits the event `RoninTrustedOrganizationContractUpdated`.\\n *\\n */\\n function setRoninTrustedOrganizationContract(address) external;\\n}\\n\",\"keccak256\":\"0x8ec2782f28a2c41d8feee0c5f213ac66e327c3757eab8d85a09104f21587ff10\",\"license\":\"MIT\"},\"contracts/interfaces/consumers/ChainTypeConsumer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ChainTypeConsumer {\\n enum ChainType {\\n RoninChain,\\n Mainchain\\n }\\n}\\n\",\"keccak256\":\"0xe0d20e00c8d237f8e0fb881abf1ff1ef114173bcb428f06f689c581666a22db7\",\"license\":\"MIT\"},\"contracts/interfaces/consumers/SignatureConsumer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface SignatureConsumer {\\n struct Signature {\\n uint8 v;\\n bytes32 r;\\n bytes32 s;\\n }\\n}\\n\",\"keccak256\":\"0xd370e350722067097dec1a5c31bda6e47e83417fa5c3288293bb910028cd136b\",\"license\":\"MIT\"},\"contracts/interfaces/consumers/VoteStatusConsumer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface VoteStatusConsumer {\\n enum VoteStatus {\\n Pending,\\n Approved,\\n Executed,\\n Rejected\\n }\\n}\\n\",\"keccak256\":\"0xc2f5e7cf4fdc18b990b3829e4ba479cd7aa0c5ea553a39dc3f1bf2e9aaed38df\",\"license\":\"MIT\"},\"contracts/interfaces/consumers/WeightedAddressConsumer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface WeightedAddressConsumer {\\n struct WeightedAddress {\\n address addr;\\n uint256 weight;\\n }\\n}\\n\",\"keccak256\":\"0xc141bda51591ca368cf9263df1b10cdb298583a4fe5104160eeaa4cf39f32763\",\"license\":\"MIT\"},\"contracts/libraries/Ballot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\n\\nlibrary Ballot {\\n using ECDSA for bytes32;\\n\\n enum VoteType {\\n For,\\n Against\\n }\\n\\n // keccak256(\\\"Ballot(bytes32 proposalHash,uint8 support)\\\");\\n bytes32 public constant BALLOT_TYPEHASH = 0xd900570327c4c0df8dd6bdd522b7da7e39145dd049d2fd4602276adcd511e3c2;\\n\\n function hash(bytes32 _proposalHash, VoteType _support) internal pure returns (bytes32) {\\n return keccak256(abi.encode(BALLOT_TYPEHASH, _proposalHash, _support));\\n }\\n}\\n\",\"keccak256\":\"0x28a0192db886307f30ada203bdb902749ee3f30d42710de4eaf303cba23c32c2\",\"license\":\"MIT\"},\"contracts/libraries/BridgeOperatorsBallot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../interfaces/consumers/WeightedAddressConsumer.sol\\\";\\n\\nlibrary BridgeOperatorsBallot {\\n // keccak256(\\\"BridgeOperatorsBallot(uint256 period,address[] operators)\\\");\\n bytes32 public constant BRIDGE_OPERATORS_BALLOT_TYPEHASH =\\n 0xeea5e3908ac28cbdbbce8853e49444c558a0a03597e98ef19e6ff86162ed9ae3;\\n\\n /**\\n * @dev Returns hash of the ballot.\\n */\\n function hash(uint256 _period, address[] memory _operators) internal pure returns (bytes32) {\\n bytes32 _operatorsHash;\\n assembly {\\n _operatorsHash := keccak256(add(_operators, 32), mul(mload(_operators), 32))\\n }\\n\\n return keccak256(abi.encode(BRIDGE_OPERATORS_BALLOT_TYPEHASH, _period, _operatorsHash));\\n }\\n}\\n\",\"keccak256\":\"0xe90d38a54b9029912a3e58f58a595da8ea285d3775d1ad798651e94f7ec83ab6\",\"license\":\"MIT\"},\"contracts/libraries/GlobalProposal.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./Proposal.sol\\\";\\n\\nlibrary GlobalProposal {\\n enum TargetOption {\\n RoninTrustedOrganizationContract,\\n GatewayContract\\n }\\n\\n struct GlobalProposalDetail {\\n // Nonce to make sure proposals are executed in order\\n uint256 nonce;\\n uint256 expiryTimestamp;\\n TargetOption[] targetOptions;\\n uint256[] values;\\n bytes[] calldatas;\\n uint256[] gasAmounts;\\n }\\n\\n // keccak256(\\\"GlobalProposalDetail(uint256 nonce,uint256 expiryTimestamp,uint8[] targetOptions,uint256[] values,bytes[] calldatas,uint256[] gasAmounts)\\\");\\n bytes32 public constant TYPE_HASH = 0x1463f426c05aff2c1a7a0957a71c9898bc8b47142540538e79ee25ee91141350;\\n\\n /**\\n * @dev Returns struct hash of the proposal.\\n */\\n function hash(GlobalProposalDetail memory _proposal) internal pure returns (bytes32) {\\n bytes32 _targetsHash;\\n bytes32 _valuesHash;\\n bytes32 _calldatasHash;\\n bytes32 _gasAmountsHash;\\n\\n uint256[] memory _values = _proposal.values;\\n TargetOption[] memory _targets = _proposal.targetOptions;\\n bytes32[] memory _calldataHashList = new bytes32[](_proposal.calldatas.length);\\n uint256[] memory _gasAmounts = _proposal.gasAmounts;\\n\\n for (uint256 _i; _i < _calldataHashList.length; _i++) {\\n _calldataHashList[_i] = keccak256(_proposal.calldatas[_i]);\\n }\\n\\n assembly {\\n _targetsHash := keccak256(add(_targets, 32), mul(mload(_targets), 32))\\n _valuesHash := keccak256(add(_values, 32), mul(mload(_values), 32))\\n _calldatasHash := keccak256(add(_calldataHashList, 32), mul(mload(_calldataHashList), 32))\\n _gasAmountsHash := keccak256(add(_gasAmounts, 32), mul(mload(_gasAmounts), 32))\\n }\\n\\n return\\n keccak256(\\n abi.encode(\\n TYPE_HASH,\\n _proposal.nonce,\\n _proposal.expiryTimestamp,\\n _targetsHash,\\n _valuesHash,\\n _calldatasHash,\\n _gasAmountsHash\\n )\\n );\\n }\\n\\n /**\\n * @dev Converts into the normal proposal.\\n */\\n function into_proposal_detail(\\n GlobalProposalDetail memory _proposal,\\n address _roninTrustedOrganizationContract,\\n address _gatewayContract\\n ) internal pure returns (Proposal.ProposalDetail memory _detail) {\\n _detail.nonce = _proposal.nonce;\\n _detail.expiryTimestamp = _proposal.expiryTimestamp;\\n _detail.chainId = 0;\\n _detail.targets = new address[](_proposal.targetOptions.length);\\n _detail.values = _proposal.values;\\n _detail.calldatas = _proposal.calldatas;\\n _detail.gasAmounts = _proposal.gasAmounts;\\n\\n for (uint256 _i; _i < _proposal.targetOptions.length; _i++) {\\n if (_proposal.targetOptions[_i] == TargetOption.GatewayContract) {\\n _detail.targets[_i] = _gatewayContract;\\n } else if (_proposal.targetOptions[_i] == TargetOption.RoninTrustedOrganizationContract) {\\n _detail.targets[_i] = _roninTrustedOrganizationContract;\\n } else {\\n revert(\\\"GlobalProposal: unsupported target\\\");\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4749e811eebe029ac572b48e5c755bc852cc74e8234c5243a57f7536c3ed00e0\",\"license\":\"MIT\"},\"contracts/libraries/Proposal.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nlibrary Proposal {\\n struct ProposalDetail {\\n // Nonce to make sure proposals are executed in order\\n uint256 nonce;\\n // Value 0: all chain should run this proposal\\n // Other values: only specifc chain has to execute\\n uint256 chainId;\\n uint256 expiryTimestamp;\\n address[] targets;\\n uint256[] values;\\n bytes[] calldatas;\\n uint256[] gasAmounts;\\n }\\n\\n // keccak256(\\\"ProposalDetail(uint256 nonce,uint256 chainId,uint256 expiryTimestamp,address[] targets,uint256[] values,bytes[] calldatas,uint256[] gasAmounts)\\\");\\n bytes32 public constant TYPE_HASH = 0xd051578048e6ff0bbc9fca3b65a42088dbde10f36ca841de566711087ad9b08a;\\n\\n /**\\n * @dev Validates the proposal.\\n */\\n function validate(ProposalDetail memory _proposal, uint256 _maxExpiryDuration) internal view {\\n require(\\n _proposal.targets.length > 0 &&\\n _proposal.targets.length == _proposal.values.length &&\\n _proposal.targets.length == _proposal.calldatas.length &&\\n _proposal.targets.length == _proposal.gasAmounts.length,\\n \\\"Proposal: invalid array length\\\"\\n );\\n require(_proposal.expiryTimestamp <= block.timestamp + _maxExpiryDuration, \\\"Proposal: invalid expiry timestamp\\\");\\n }\\n\\n /**\\n * @dev Returns struct hash of the proposal.\\n */\\n function hash(ProposalDetail memory _proposal) internal pure returns (bytes32) {\\n bytes32 _targetsHash;\\n bytes32 _valuesHash;\\n bytes32 _calldatasHash;\\n bytes32 _gasAmountsHash;\\n\\n uint256[] memory _values = _proposal.values;\\n address[] memory _targets = _proposal.targets;\\n bytes32[] memory _calldataHashList = new bytes32[](_proposal.calldatas.length);\\n uint256[] memory _gasAmounts = _proposal.gasAmounts;\\n\\n for (uint256 _i; _i < _calldataHashList.length; _i++) {\\n _calldataHashList[_i] = keccak256(_proposal.calldatas[_i]);\\n }\\n\\n assembly {\\n _targetsHash := keccak256(add(_targets, 32), mul(mload(_targets), 32))\\n _valuesHash := keccak256(add(_values, 32), mul(mload(_values), 32))\\n _calldatasHash := keccak256(add(_calldataHashList, 32), mul(mload(_calldataHashList), 32))\\n _gasAmountsHash := keccak256(add(_gasAmounts, 32), mul(mload(_gasAmounts), 32))\\n }\\n\\n return\\n keccak256(\\n abi.encode(\\n TYPE_HASH,\\n _proposal.nonce,\\n _proposal.chainId,\\n _proposal.expiryTimestamp,\\n _targetsHash,\\n _valuesHash,\\n _calldatasHash,\\n _gasAmountsHash\\n )\\n );\\n }\\n\\n /**\\n * @dev Returns whether the proposal is executable for the current chain.\\n *\\n * @notice Does not check whether the call result is successful or not. Please use `execute` instead.\\n *\\n */\\n function executable(ProposalDetail memory _proposal) internal view returns (bool _result) {\\n return _proposal.chainId == 0 || _proposal.chainId == block.chainid;\\n }\\n\\n /**\\n * @dev Executes the proposal.\\n */\\n function execute(ProposalDetail memory _proposal)\\n internal\\n returns (bool[] memory _successCalls, bytes[] memory _returnDatas)\\n {\\n require(executable(_proposal), \\\"Proposal: query for invalid chainId\\\");\\n _successCalls = new bool[](_proposal.targets.length);\\n _returnDatas = new bytes[](_proposal.targets.length);\\n for (uint256 _i = 0; _i < _proposal.targets.length; ++_i) {\\n require(gasleft() > _proposal.gasAmounts[_i], \\\"Proposal: insufficient gas\\\");\\n\\n (_successCalls[_i], _returnDatas[_i]) = _proposal.targets[_i].call{\\n value: _proposal.values[_i],\\n gas: _proposal.gasAmounts[_i]\\n }(_proposal.calldatas[_i]);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x96bf9eaea9a87a5eceed026a6eaedc74cf5dde6760f7e969d5b5974dad43ff80\",\"license\":\"MIT\"},\"contracts/ronin/RoninGovernanceAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"../extensions/isolated-governance/bridge-operator-governance/BOsGovernanceProposal.sol\\\";\\nimport \\\"../extensions/sequential-governance/GovernanceProposal.sol\\\";\\nimport \\\"../extensions/GovernanceAdmin.sol\\\";\\nimport \\\"../interfaces/IBridge.sol\\\";\\n\\ncontract RoninGovernanceAdmin is GovernanceAdmin, GovernanceProposal, BOsGovernanceProposal {\\n /// @dev Emitted when the bridge operators are approved.\\n event BridgeOperatorsApproved(uint256 _period, address[] _operators);\\n\\n modifier onlyGovernor() {\\n require(_getWeight(msg.sender) > 0, \\\"GovernanceAdmin: sender is not governor\\\");\\n _;\\n }\\n\\n constructor(\\n address _roninTrustedOrganizationContract,\\n address _bridgeContract,\\n uint256 _proposalExpiryDuration\\n ) GovernanceAdmin(_roninTrustedOrganizationContract, _bridgeContract, _proposalExpiryDuration) {}\\n\\n /**\\n * @dev Returns the voted signatures for the proposals.\\n *\\n */\\n function getProposalSignatures(uint256 _chainId, uint256 _round)\\n external\\n view\\n returns (Ballot.VoteType[] memory _supports, Signature[] memory _signatures)\\n {\\n ProposalVote storage _vote = vote[_chainId][_round];\\n\\n uint256 _forLength = _vote.forVoteds.length;\\n uint256 _againstLength = _vote.againstVoteds.length;\\n uint256 _voterLength = _forLength + _againstLength;\\n\\n _supports = new Ballot.VoteType[](_voterLength);\\n _signatures = new Signature[](_voterLength);\\n for (uint256 _i; _i < _forLength; _i++) {\\n _supports[_i] = Ballot.VoteType.For;\\n _signatures[_i] = vote[_chainId][_round].sig[_vote.forVoteds[_i]];\\n }\\n for (uint256 _i; _i < _againstLength; _i++) {\\n _supports[_i + _forLength] = Ballot.VoteType.Against;\\n _signatures[_i + _forLength] = vote[_chainId][_round].sig[_vote.againstVoteds[_i]];\\n }\\n }\\n\\n /**\\n * @dev Returns the voted signatures for bridge operators at a specific period.\\n *\\n * Note: Does not verify whether the voter casted vote for the proposal and the returned signature can be empty.\\n * Please consider filtering for empty signatures after calling this function.\\n *\\n */\\n function getBridgeOperatorVotingSignatures(uint256 _period, address[] calldata _voters)\\n external\\n view\\n returns (Signature[] memory _signatures)\\n {\\n _signatures = new Signature[](_voters.length);\\n for (uint256 _i; _i < _voters.length; _i++) {\\n _signatures[_i] = _votingSig[_period][_voters[_i]];\\n }\\n }\\n\\n /**\\n * @dev Returns whether the voter `_voter` casted vote for the proposal.\\n */\\n function proposalVoted(\\n uint256 _chainId,\\n uint256 _round,\\n address _voter\\n ) external view returns (bool) {\\n return _voted(vote[_chainId][_round], _voter);\\n }\\n\\n /**\\n * @dev Returns whether the voter `_voter` casted vote for bridge operators at a specific period.\\n */\\n function bridgeOperatorsVoted(uint256 _period, address _voter) external view returns (bool) {\\n return _voted(_vote[_period], _voter);\\n }\\n\\n /**\\n * @dev See `CoreGovernance-_proposeProposal`.\\n *\\n * Requirements:\\n * - The method caller is governor.\\n *\\n */\\n function propose(\\n uint256 _chainId,\\n uint256 _expiryTimestamp,\\n address[] calldata _targets,\\n uint256[] calldata _values,\\n bytes[] calldata _calldatas,\\n uint256[] calldata _gasAmounts\\n ) external onlyGovernor {\\n _proposeProposal(_chainId, _expiryTimestamp, _targets, _values, _calldatas, _gasAmounts, msg.sender);\\n }\\n\\n /**\\n * @dev See `GovernanceProposal-_proposeProposalStructAndCastVotes`.\\n *\\n * Requirements:\\n * - The method caller is governor.\\n *\\n */\\n function proposeProposalStructAndCastVotes(\\n Proposal.ProposalDetail calldata _proposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures\\n ) external onlyGovernor {\\n _proposeProposalStructAndCastVotes(_proposal, _supports, _signatures, DOMAIN_SEPARATOR, msg.sender);\\n }\\n\\n /**\\n * @dev See `GovernanceProposal-_castProposalBySignatures`.\\n */\\n function castProposalBySignatures(\\n Proposal.ProposalDetail calldata _proposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures\\n ) external {\\n _castProposalBySignatures(_proposal, _supports, _signatures, DOMAIN_SEPARATOR);\\n }\\n\\n /**\\n * @dev See `CoreGovernance-_proposeGlobal`.\\n *\\n * Requirements:\\n * - The method caller is governor.\\n *\\n */\\n function proposeGlobal(\\n uint256 _expiryTimestamp,\\n GlobalProposal.TargetOption[] calldata _targetOptions,\\n uint256[] calldata _values,\\n bytes[] calldata _calldatas,\\n uint256[] calldata _gasAmounts\\n ) external onlyGovernor {\\n _proposeGlobal(\\n _expiryTimestamp,\\n _targetOptions,\\n _values,\\n _calldatas,\\n _gasAmounts,\\n roninTrustedOrganizationContract(),\\n bridgeContract(),\\n msg.sender\\n );\\n }\\n\\n /**\\n * @dev See `GovernanceProposal-_proposeGlobalProposalStructAndCastVotes`.\\n *\\n * Requirements:\\n * - The method caller is governor.\\n *\\n */\\n function proposeGlobalProposalStructAndCastVotes(\\n GlobalProposal.GlobalProposalDetail calldata _globalProposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures\\n ) external onlyGovernor {\\n _proposeGlobalProposalStructAndCastVotes(\\n _globalProposal,\\n _supports,\\n _signatures,\\n DOMAIN_SEPARATOR,\\n roninTrustedOrganizationContract(),\\n bridgeContract(),\\n msg.sender\\n );\\n }\\n\\n /**\\n * @dev See `GovernanceProposal-_castGlobalProposalBySignatures`.\\n */\\n function castGlobalProposalBySignatures(\\n GlobalProposal.GlobalProposalDetail calldata _globalProposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures\\n ) external {\\n _castGlobalProposalBySignatures(\\n _globalProposal,\\n _supports,\\n _signatures,\\n DOMAIN_SEPARATOR,\\n roninTrustedOrganizationContract(),\\n bridgeContract()\\n );\\n }\\n\\n /**\\n * @dev See `CoreGovernance-_deleteExpiredProposal`\\n */\\n function deleteExpired(uint256 chainId, uint256 round) external {\\n _deleteExpiredVotingRound(chainId, round);\\n }\\n\\n /**\\n * @dev See `BOsGovernanceProposal-_castVotesBySignatures`.\\n */\\n function voteBridgeOperatorsBySignatures(\\n uint256 _period,\\n address[] calldata _operators,\\n Signature[] calldata _signatures\\n ) external {\\n _castVotesBySignatures(_operators, _signatures, _period, _getMinimumVoteWeight(), DOMAIN_SEPARATOR);\\n IsolatedVote storage _v = _vote[_period];\\n if (_v.status == VoteStatus.Approved) {\\n _lastSyncedPeriod = _period;\\n emit BridgeOperatorsApproved(_period, _operators);\\n _v.status = VoteStatus.Executed;\\n }\\n }\\n\\n /**\\n * @inheritdoc GovernanceProposal\\n */\\n function _getWeight(address _governor) internal view virtual override returns (uint256) {\\n (bool _success, bytes memory _returndata) = roninTrustedOrganizationContract().staticcall(\\n abi.encodeWithSelector(\\n // TransparentUpgradeableProxyV2.functionDelegateCall.selector,\\n 0x4bb5274a,\\n abi.encodeWithSelector(IRoninTrustedOrganization.getGovernorWeight.selector, _governor)\\n )\\n );\\n require(_success, \\\"GovernanceAdmin: proxy call `getGovernorWeight(address)` failed\\\");\\n return abi.decode(_returndata, (uint256));\\n }\\n\\n /**\\n * @inheritdoc BOsGovernanceProposal\\n */\\n function _getBridgeVoterWeight(address _governor) internal view virtual override returns (uint256) {\\n (bool _success, bytes memory _returndata) = roninTrustedOrganizationContract().staticcall(\\n abi.encodeWithSelector(\\n // TransparentUpgradeableProxyV2.functionDelegateCall.selector,\\n 0x4bb5274a,\\n abi.encodeWithSelector(IRoninTrustedOrganization.getBridgeVoterWeight.selector, _governor)\\n )\\n );\\n require(_success, \\\"GovernanceAdmin: proxy call `getBridgeVoterWeight(address)` failed\\\");\\n return abi.decode(_returndata, (uint256));\\n }\\n\\n /**\\n * @dev See {CoreGovernance-_getChainType}\\n */\\n function _getChainType() internal pure override returns (ChainType) {\\n return ChainType.RoninChain;\\n }\\n}\\n\",\"keccak256\":\"0xb56e369ff4035b55e8f29b0162e729993d47abff785f25e58aabc1a50720f1d5\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b5060405162004d4838038062004d48833981016040819052620000349162000288565b828282806200004281600255565b50604080516020808201839052601660608301527f524f4e494e5f474f5645524e414e43455f41444d494e000000000000000000006080808401919091526107e4838501528351808403909101815260a0830184528051908201207f599a80fcaa47b95e2323ab4d34d34e0cc9feda4b843edafcc30c7bdf60ea15bf60c08401527f7e7935007966eb860f4a2ee3dcc9fd53fb3205ce2aa86b0126d4893d4d4c14b960e08401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6610100840152610120808401919091528351808403909101815261014090920190925280519101207ff8704f8860d9e985bf6c52ec4738bd10fe31487599b36c0944f746ea09dc256b14620001a55760405162461bcd60e51b815260206004820152601f60248201527f476f7665726e616e636541646d696e3a20696e76616c696420646f6d61696e00604482015260640160405180910390fd5b620001b083620001c7565b620001bb826200021c565b505050505050620002c9565b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527ffd6f5f93d69a07c593a09be0b208bff13ab4ffd6017df3b33433d63bdc59b4d7906020015b60405180910390a150565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5cbd8a0bb00196365d5eb3457c6734e7f06666c3c78e5469b4c9deec7edae0489060200162000211565b80516001600160a01b03811681146200028357600080fd5b919050565b6000806000606084860312156200029e57600080fd5b620002a9846200026b565b9250620002b9602085016200026b565b9150604084015190509250925092565b614a6f80620002d96000396000f3fe608060405234801561001057600080fd5b50600436106101725760003560e01c80633644e515116100de578063a1819f9a11610097578063bc96180b11610071578063bc96180b146103c9578063cd596583146103d1578063f3b7dead146103e2578063fb4f6371146103f557600080fd5b8063a1819f9a14610348578063b384abef1461035b578063b5e337de146103b657600080fd5b80633644e515146102c05780635511cde1146102d557806356e237e8146102e65780637eff275e146102f9578063988ef53c1461030c5780639a7d33821461033557600080fd5b8063204e1c7a11610130578063204e1c7a1461020e5780632c5e6520146102395780632e96a6fb1461024c5780632faf925d1461025f578063332635be1461027257806334d5f37b1461029257600080fd5b80624054b814610177578063055c68891461018c57806309fcd8c7146101b45780630b26cf66146101c75780630b881830146101da5780631c905e39146101ed575b600080fd5b61018a610185366004613949565b610408565b005b61019f61019a3660046139fa565b61045d565b60405190151581526020015b60405180910390f35b61018a6101c2366004613a2a565b61048f565b61018a6101d5366004613af9565b610558565b61018a6101e8366004613949565b6105ad565b6102006101fb366004613b16565b6105c9565b6040516101ab929190613bb2565b61022161021c366004613af9565b6108c7565b6040516001600160a01b0390911681526020016101ab565b61019f610247366004613c12565b6109b9565b61018a61025a366004613c4b565b6109ef565b61018a61026d366004613c64565b610a17565b610285610280366004613ca7565b610a51565b6040516101ab9190613cf2565b6102b26102a0366004613c4b565b60006020819052908152604090205481565b6040519081526020016101ab565b6102b2600080516020614a1a83398151915281565b6003546001600160a01b0316610221565b61018a6102f4366004613d05565b610b82565b61018a610307366004613d3b565b610c26565b6102b261031a366004613af9565b6001600160a01b031660009081526007602052604090205490565b61018a610343366004613b16565b610d57565b61018a610356366004613d69565b610d65565b6103a5610369366004613b16565b600160208181526000938452604080852090915291835291208054918101546002820154600383015460069093015460ff909416939192909185565b6040516101ab959493929190613e42565b61018a6103c4366004613af9565b610e4b565b6102b2610e9d565b6004546001600160a01b0316610221565b6102216103f0366004613af9565b610ead565b61018a610403366004613c64565b610f7a565b600061041333610fdd565b116104395760405162461bcd60e51b815260040161043090613e77565b60405180910390fd5b6104568585858585600080516020614a1a83398151915233611151565b5050505050565b60008281526006602090815260408083206001600160a01b038516845260020190915281205415155b90505b92915050565b600061049a33610fdd565b116104b75760405162461bcd60e51b815260040161043090613e77565b61054c8989898989808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506104fd92508a91508b9050614041565b87878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061053a9250610b73915050565b6004546001600160a01b0316336111bb565b50505050505050505050565b3330146105775760405162461bcd60e51b81526004016104309061404e565b6000816001600160a01b03163b116105a15760405162461bcd60e51b815260040161043090614095565b6105aa816112f0565b50565b6104568585858585600080516020614a1a833981519152611345565b600082815260016020908152604080832084845290915281206004810154600582015460609384939291906105fe82846140ef565b9050806001600160401b0381111561061857610618613ebe565b604051908082528060200260200182016040528015610641578160200160208202803683370190505b509550806001600160401b0381111561065c5761065c613ebe565b6040519080825280602002602001820160405280156106a757816020015b604080516060810182526000808252602080830182905292820152825260001990920191018161067a5790505b50945060005b838110156107aa5760008782815181106106c9576106c9614102565b602002602001019060018111156106e2576106e2613b38565b908160018111156106f5576106f5613b38565b90525060008981526001602090815260408083208b84529091528120600487018054600790920192918490811061072e5761072e614102565b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815460ff1681526001820154938101939093526002015490820152865187908390811061078c5761078c614102565b602002602001018190525080806107a290614118565b9150506106ad565b5060005b828110156108bb576001876107c386846140ef565b815181106107d3576107d3614102565b602002602001019060018111156107ec576107ec613b38565b908160018111156107ff576107ff613b38565b90525060008981526001602090815260408083208b84529091528120600587018054600790920192918490811061083857610838614102565b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815460ff16815260018201549381019390935260020154908201528661088d86846140ef565b8151811061089d5761089d614102565b602002602001018190525080806108b390614118565b9150506107ae565b50505050509250929050565b6000806000836001600160a01b03166040516108ed90635c60da1b60e01b815260040190565b600060405180830381855afa9150503d8060008114610928576040519150601f19603f3d011682016040523d82523d6000602084013e61092d565b606091505b50915091508161099d5760405162461bcd60e51b815260206004820152603560248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c2060696d706044820152741b195b595b9d185d1a5bdb8a0a580819985a5b1959605a1b6064820152608401610430565b808060200190518101906109b19190614131565b949350505050565b600083815260016020818152604080842086855282528084206001600160a01b03861685526007019091528220015415156109b1565b333014610a0e5760405162461bcd60e51b81526004016104309061404e565b6105aa81600255565b6104568585858585600080516020614a1a833981519152610a406003546001600160a01b031690565b6004546001600160a01b03166113cc565b6060816001600160401b03811115610a6b57610a6b613ebe565b604051908082528060200260200182016040528015610ab657816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181610a895790505b50905060005b82811015610b6b57600085815260086020526040812090858584818110610ae557610ae5614102565b9050602002016020810190610afa9190613af9565b6001600160a01b0316815260208082019290925260409081016000208151606081018352815460ff16815260018201549381019390935260020154908201528251839083908110610b4d57610b4d614102565b60200260200101819052508080610b6390614118565b915050610abc565b509392505050565b6003546001600160a01b031690565b610ba68484848489610b92611480565b600080516020614a1a8339815191526115ec565b60008581526006602052604090206001815460ff166003811115610bcc57610bcc613b38565b03610c1e5760058690556040517f1599b04a1104d19ef534dc177f3de0164ef5e4b99fad7485eda134600fca5f0290610c0a9088908890889061414e565b60405180910390a1805460ff191660021781555b505050505050565b333014610c455760405162461bcd60e51b81526004016104309061404e565b604080516001600160a01b0383811660248084019190915283518084039091018152604490920183526020820180516001600160e01b03166308f2839760e41b1790529151600092851691610c99916141ca565b6000604051808303816000865af19150503d8060008114610cd6576040519150601f19603f3d011682016040523d82523d6000602084013e610cdb565b606091505b5050905080610d525760405162461bcd60e51b815260206004820152603960248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c206063686160448201527f6e676541646d696e28616464726573732960206661696c6564000000000000006064820152608401610430565b505050565b610d618282611924565b5050565b6000610d7033610fdd565b11610d8d5760405162461bcd60e51b815260040161043090613e77565b610e3e8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c918291850190849080828437600092019190915250610e0392508a91508b9050614041565b87878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525033925061194c915050565b5050505050505050505050565b333014610e6a5760405162461bcd60e51b81526004016104309061404e565b6000816001600160a01b03163b11610e945760405162461bcd60e51b815260040161043090614095565b6105aa81611a64565b6000610ea860025490565b905090565b6000806000836001600160a01b0316604051610ed3906303e1469160e61b815260040190565b600060405180830381855afa9150503d8060008114610f0e576040519150601f19603f3d011682016040523d82523d6000602084013e610f13565b606091505b50915091508161099d5760405162461bcd60e51b815260206004820152602c60248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c206061646d60448201526b1a5b8a0a580819985a5b195960a21b6064820152608401610430565b6000610f8533610fdd565b11610fa25760405162461bcd60e51b815260040161043090613e77565b610c1e8585858585600080516020614a1a833981519152610fcb6003546001600160a01b031690565b6004546001600160a01b031633611ab2565b6000806000610ff46003546001600160a01b031690565b604080516001600160a01b03878116602480840191909152835180840382018152604490930184526020830180516001600160e01b0316631af0725f60e31b1790529251931692634bb5274a9261104c929101614212565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161108591906141ca565b600060405180830381855afa9150503d80600081146110c0576040519150601f19603f3d011682016040523d82523d6000602084013e6110c5565b606091505b50915091508161113d5760405162461bcd60e51b815260206004820152603f60248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c206067657460448201527f476f7665726e6f7257656967687428616464726573732960206661696c6564006064820152608401610430565b808060200190518101906109b19190614225565b61116361115d88614328565b82611b15565b50600061117761117289614328565b611bfd565b90506111b161118589614328565b8888888861119d89611198896000611d9c565b611df2565b6111ac8a6111988a6001611d9c565b611e19565b5050505050505050565b6040805160c08101909152600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5549091829181906112039060016140ef565b81526020018c81526020018b8b808060200260200160405190810160405280939291908181526020018383602002808284376000920182905250938552505050602082018b9052604082018a90526060909101889052909150611267828787612172565b905061127e6002548261233890919063ffffffff16565b600061128982611bfd565b90506112976000828f612434565b935080847f771d78ae9e5fca95a532fb0971d575d0ce9b59d14823c063e08740137e0e0eca846112c687612562565b878a6040516112d89493929190614544565b60405180910390a35050509998505050505050505050565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5cbd8a0bb00196365d5eb3457c6734e7f06666c3c78e5469b4c9deec7edae048906020015b60405180910390a150565b600061135361117288614328565b6020808901356000908152600180835260408083208c358452909352919020015490915081146113955760405162461bcd60e51b81526004016104309061462b565b6113c36113a188614328565b878787876113b488611198896000611d9c565b6111ac896111988a6001611d9c565b50505050505050565b60006113e383836113dc8c6146eb565b9190612172565b905060006113f86113f38b6146eb565b612562565b905061140382611bfd565b600080805260016020818152855183527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb499052604090912001541461145a5760405162461bcd60e51b81526004016104309061462b565b61054c828a8a8a8a6114718b611198896000611d9c565b6111ac8c6111988a6001611d9c565b60008060006114976003546001600160a01b031690565b6040805160048152602480820183526020820180516001600160e01b0316637de5dedd60e01b17905291516001600160a01b039390931692634bb5274a926114e0929101614212565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161151991906141ca565b600060405180830381855afa9150503d8060008114611554576040519150601f19603f3d011682016040523d82523d6000602084013e611559565b606091505b5091509150816115d15760405162461bcd60e51b815260206004820152603860248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c20606d696e60448201527f696d756d566f7465576569676874282960206661696c656400000000000000006064820152608401610430565b808060200190518101906115e59190614225565b9250505090565b6005548310156116575760405162461bcd60e51b815260206004820152603060248201527f424f73476f7665726e616e636550726f706f73616c3a20717565727920666f7260448201526f081bdd5d19185d1959081c195c9a5bd960821b6064820152608401610430565b851580159061166557508315155b6116c55760405162461bcd60e51b815260206004820152602b60248201527f424f73476f7665726e616e636550726f706f73616c3a20696e76616c6964206160448201526a0e4e4c2f240d8cadccee8d60ab1b6064820152608401610430565b60408051606081018252600080825260208201819052918101919091526000806000611724878c8c808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506126bc92505050565b905060006117328683611df2565b6000898152600660205260408120919250805b8b8110156118b4578c8c8281811061175f5761175f614102565b90506060020180360381019061177591906147b5565b975061178f8489600001518a602001518b6040015161271d565b9650866001600160a01b0316866001600160a01b0316106117fe5760405162461bcd60e51b8152602060048201526024808201527f424f73476f7665726e616e636550726f706f73616c3a20696e76616c6964206f604482015263393232b960e11b6064820152608401610430565b869550600061180c88612745565b905080156118a1576001600160a01b03881660008181526007602090815260408083204390558f835260088252808320938352928152908290208b51815460ff191660ff909116178155908b0151600180830191909155918b015160029091015592508261187d858a848f8b6128b0565b600381111561188e5761188e613b38565b036118a1575050505050505050506113c3565b50806118ac81614118565b915050611745565b50806119145760405162461bcd60e51b815260206004820152602960248201527f424f73476f7665726e616e636550726f706f73616c3a20696e76616c6964207360448201526869676e61747572657360b81b6064820152608401610430565b5050505050505050505050505050565b60008281526001602090815260408083208484529091529020611946816129ac565b50505050565b60008760000361199e5760405162461bcd60e51b815260206004820181905260248201527f436f7265476f7665726e616e63653a20696e76616c696420636861696e2069646044820152606401610430565b6040805160e08101825260008a815260208190529182205481906119c39060016140ef565b81526020018a8152602001898152602001888152602001878152602001868152602001858152509050611a016002548261233890919063ffffffff16565b6000611a0c82611bfd565b9050611a198a828b612434565b925080838b7fa57d40f1496988cf60ab7c9d5ba4ff83647f67d3898d441a3aaf21b651678fd98588604051611a4f92919061481c565b60405180910390a45050979650505050505050565b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527ffd6f5f93d69a07c593a09be0b208bff13ab4ffd6017df3b33433d63bdc59b4d79060200161133a565b611aba61384b565b611ace611ac68b6146eb565b858585612b18565b5090506000611adf6113f38c6146eb565b9050611b07828b8b8b8b611af88c611198896000611d9c565b6111ac8d6111988a6001611d9c565b509998505050505050505050565b6020820151600090808203611b6c5760405162461bcd60e51b815260206004820181905260248201527f436f7265476f7665726e616e63653a20696e76616c696420636861696e2069646044820152606401610430565b600254611b7a908590612338565b6000611b8585611bfd565b9050611b9682828760400151612434565b85519093508314611bb95760405162461bcd60e51b815260040161043090614846565b8083837fa57d40f1496988cf60ab7c9d5ba4ff83647f67d3898d441a3aaf21b651678fd98888604051611bed92919061481c565b60405180910390a4505092915050565b6000806000806000808660800151905060008760600151905060008860a00151516001600160401b03811115611c3557611c35613ebe565b604051908082528060200260200182016040528015611c5e578160200160208202803683370190505b5060c08a015190915060005b8251811015611cc7578a60a001518181518110611c8957611c89614102565b602002602001015180519060200120838281518110611caa57611caa614102565b602090810291909101015280611cbf81614118565b915050611c6a565b506020835102602084012097506020845102602085012096506020825102602083012095506020815102602082012094507fd051578048e6ff0bbc9fca3b65a42088dbde10f36ca841de566711087ad9b08a60001b8a600001518b602001518c604001518b8b8b8b604051602001611d77989796959493929190978852602088019690965260408701949094526060860192909252608085015260a084015260c083015260e08201526101000190565b6040516020818303038152906040528051906020012098505050505050505050919050565b604051600090611dd4907fd900570327c4c0df8dd6bdd522b7da7e39145dd049d2fd4602276adcd511e3c2908590859060200161488c565b60405160208183030381529060405280519060200120905092915050565b60405161190160f01b60208201526022810183905260428101829052600090606201611dd4565b8415801590611e2757508483145b611e845760405162461bcd60e51b815260206004820152602860248201527f476f7665726e616e636550726f706f73616c3a20696e76616c696420617272616044820152670f240d8cadccee8d60c31b6064820152608401610430565b6000611e8e611480565b9050600081611e9b612bd5565b611ea591906148b1565b611eb09060016140ef565b9050600080611ed8604080516060810182526000808252602082018190529181019190915290565b6000805b89811015612106578a8a82818110611ef657611ef6614102565b905060600201803603810190611f0c91906147b5565b925060008d8d83818110611f2257611f22614102565b9050602002016020810190611f3791906148c4565b6001811115611f4857611f48613b38565b03611f6c57611f658984600001518560200151866040015161271d565b9350612027565b60018d8d83818110611f8057611f80614102565b9050602002016020810190611f9591906148c4565b6001811115611fa657611fa6613b38565b03611fc357611f658884600001518560200151866040015161271d565b60405162461bcd60e51b815260206004820152603360248201527f476f7665726e616e636550726f706f73616c3a20717565727920666f7220756e604482015272737570706f7274656420766f7465207479706560681b6064820152608401610430565b836001600160a01b0316856001600160a01b0316106120925760405162461bcd60e51b815260206004820152602160248201527f476f7665726e616e636550726f706f73616c3a20696e76616c6964206f7264656044820152603960f91b6064820152608401610430565b83945060006120a085610fdd565b905080156120f357600192506120e18f8f8f858181106120c2576120c2614102565b90506020020160208101906120d791906148c4565b8a8a898987612d1c565b156120f35750505050505050506113c3565b50806120fe81614118565b915050611edc565b50806121635760405162461bcd60e51b815260206004820152602660248201527f476f7665726e616e636550726f706f73616c3a20696e76616c6964207369676e60448201526561747572657360d01b6064820152608401610430565b50505050505050505050505050565b61217a61384b565b83518152602080850151604080840191909152600091830191909152840151516001600160401b038111156121b1576121b1613ebe565b6040519080825280602002602001820160405280156121da578160200160208202803683370190505b5060608083019190915284015160808083019190915284015160a08083019190915284015160c082015260005b846040015151811015610b6b5760018560400151828151811061222c5761222c614102565b6020026020010151600181111561224557612245613b38565b0361228657828260600151828151811061226157612261614102565b60200260200101906001600160a01b031690816001600160a01b031681525050612326565b60008560400151828151811061229e5761229e614102565b602002602001015160018111156122b7576122b7613b38565b036122d357838260600151828151811061226157612261614102565b60405162461bcd60e51b815260206004820152602260248201527f476c6f62616c50726f706f73616c3a20756e737570706f727465642074617267604482015261195d60f21b6064820152608401610430565b8061233081614118565b915050612207565b60008260600151511180156123565750816080015151826060015151145b801561236b57508160a0015151826060015151145b801561238057508160c0015151826060015151145b6123cc5760405162461bcd60e51b815260206004820152601e60248201527f50726f706f73616c3a20696e76616c6964206172726179206c656e67746800006044820152606401610430565b6123d681426140ef565b82604001511115610d615760405162461bcd60e51b815260206004820152602260248201527f50726f706f73616c3a20696e76616c6964206578706972792074696d6573746160448201526106d760f41b6064820152608401610430565b6000838152602081905260408120549081900361246557506000838152602081905260409020600190819055612535565b6000848152600160209081526040808320848452909152812090612488826129ac565b905080612532576000825460ff1660038111156124a7576124a7613b38565b0361250e5760405162461bcd60e51b815260206004820152603160248201527f436f7265476f7665726e616e63653a2063757272656e742070726f706f73616c604482015270081a5cc81b9bdd0818dbdb5c1b195d1959607a1b6064820152608401610430565b6000868152602081905260408120805490919061252a90614118565b918290555092505b50505b60009384526001602081815260408087208488529091529094209384019290925560069092019190915590565b6000806000806000808660600151905060008760400151905060008860800151516001600160401b0381111561259a5761259a613ebe565b6040519080825280602002602001820160405280156125c3578160200160208202803683370190505b5060a08a015190915060005b825181101561262c578a6080015181815181106125ee576125ee614102565b60200260200101518051906020012083828151811061260f5761260f614102565b60209081029190910101528061262481614118565b9150506125cf565b5082516020908102848201208551820286830120845183028584012084518402858501208e518f860151604080517f1463f426c05aff2c1a7a0957a71c9898bc8b47142540538e79ee25ee911413509881019890985287019190915260608601526080850184905260a0850183905260c0850182905260e08501819052929b509099509750955061010001611d77565b8051602090810291810191909120604080517feea5e3908ac28cbdbbce8853e49444c558a0a03597e98ef19e6ff86162ed9ae38185015280820194909452606080850192909252805180850390920182526080909301909252815191012090565b600080600061272e878787876130e3565b9150915061273b816131d0565b5095945050505050565b600080600061275c6003546001600160a01b031690565b604080516001600160a01b03878116602480840191909152835180840382018152604490930184526020830180516001600160e01b0316635624191160e01b1790529251931692634bb5274a926127b4929101614212565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516127ed91906141ca565b600060405180830381855afa9150503d8060008114612828576040519150601f19603f3d011682016040523d82523d6000602084013e61282d565b606091505b50915091508161113d5760405162461bcd60e51b815260206004820152604260248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c206067657460448201527f427269646765566f74657257656967687428616464726573732960206661696c606482015261195960f21b608482015260a401610430565b6001600160a01b03841660009081526002860160205260408120541561291a576128e4856001600160a01b03166014613386565b6040516020016128f491906148e1565b60408051601f198184030181529082905262461bcd60e51b825261043091600401614212565b6001600160a01b03851660009081526002870160209081526040808320859055848352600389019091528120805486919083906129589084906140ef565b925050819055905083811015801561298557506000875460ff16600381111561298357612983613b38565b145b1561299d57865460ff19166001908117885587018390555b5050935460ff16949350505050565b60068101544210801590612b135760018201546040517f58f98006a7f2f253f8ae8f8b7cec9008ca05359633561cd7c22f3005682d4a5590600090a260005b6004830154811015612a5b57826007016000846004018381548110612a1257612a12614102565b60009182526020808320909101546001600160a01b031683528201929092526040018120805460ff19168155600181018290556002015580612a5381614118565b9150506129eb565b5060005b6005830154811015612acf57826007016000846005018381548110612a8657612a86614102565b60009182526020808320909101546001600160a01b031683528201929092526040018120805460ff19168155600181018290556002015580612ac781614118565b915050612a5f565b50815460ff191682556000600183018190556002830181905560038301819055612afd906004840190613888565b612b0b600583016000613888565b600060068301555b919050565b612b2061384b565b6000612b2d868686612172565b9150612b446002548361233890919063ffffffff16565b6000612b4f83611bfd565b9050612b616000828960200151612434565b83519092508214612b845760405162461bcd60e51b815260040161043090614846565b80827f771d78ae9e5fca95a532fb0971d575d0ce9b59d14823c063e08740137e0e0eca85612bb18b612562565b8b89604051612bc39493929190614544565b60405180910390a35094509492505050565b6000806000612bec6003546001600160a01b031690565b6040805160048152602480820183526020820180516001600160e01b031663926323d560e01b17905291516001600160a01b039390931692634bb5274a92612c35929101614212565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051612c6e91906141ca565b600060405180830381855afa9150503d8060008114612ca9576040519150601f19603f3d011682016040523d82523d6000602084013e612cae565b606091505b5091509150816115d15760405162461bcd60e51b815260206004820152603360248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c2060746f74604482015272185b15d95a59da1d1cca0a580819985a5b1959606a1b6064820152608401610430565b60208088015188516000828152600184526040808220838352909452928320612d44816129ac565b15612d5557600193505050506130d8565b6020808c015160009081529081905260409020548214612dd05760405162461bcd60e51b815260206004820152603060248201527f436f7265476f7665726e616e63653a20717565727920666f7220696e76616c6960448201526f642070726f706f73616c206e6f6e636560801b6064820152608401610430565b6000815460ff166003811115612de857612de8613b38565b14612e435760405162461bcd60e51b815260206004820152602560248201527f436f7265476f7665726e616e63653a2074686520766f74652069732066696e616044820152641b1a5e995960da1b6064820152608401610430565b6001600160a01b038716600090815260078201602052604090206001015415612e8a57612e7a876001600160a01b03166014613386565b6040516020016128f49190614935565b6001600160a01b03871660008181526007830160209081526040918290208951815460ff191660ff909116178155908901516001808301919091558983015160029092019190915583015490517f1203f9e81c814a35f5f4cc24087b2a24c6fb7986a9f1406b68a9484882c93a2390612f06908e908a90614985565b60405180910390a3600080808c6001811115612f2457612f24613b38565b03612f79576004830180546001810182556000918252602082200180546001600160a01b0319166001600160a01b038c16179055600384018054899290612f6c9084906140ef565b9250508190559150613038565b60018c6001811115612f8d57612f8d613b38565b03612fe2576005830180546001810182556000918252602082200180546001600160a01b0319166001600160a01b038c16179055600284018054899290612fd59084906140ef565b9250508190559050613038565b60405162461bcd60e51b815260206004820152602560248201527f436f7265476f7665726e616e63653a20756e737570706f7274656420766f7465604482015264207479706560d81b6064820152608401610430565b8a821061308c57825460ff19166001908117845580840154604051919750907f5c819725ea53655a3b898f3df59b66489761935454e9212ca1e5ebd759953d0b90600090a2613087838e613521565b6130d2565b8981106130d257825460ff19166003178355600180840154604051919750907f55295d4ce992922fa2e5ffbf3a3dcdb367de0a15e125ace083456017fd22060f90600090a25b50505050505b979650505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561311a57506000905060036131c7565b8460ff16601b1415801561313257508460ff16601c14155b1561314357506000905060046131c7565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613197573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166131c0576000600192509250506131c7565b9150600090505b94509492505050565b60008160048111156131e4576131e4613b38565b036131ec5750565b600181600481111561320057613200613b38565b0361324d5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610430565b600281600481111561326157613261613b38565b036132ae5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610430565b60038160048111156132c2576132c2613b38565b0361331a5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610430565b600481600481111561332e5761332e613b38565b036105aa5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610430565b6060600061339583600261499c565b6133a09060026140ef565b6001600160401b038111156133b7576133b7613ebe565b6040519080825280601f01601f1916602001820160405280156133e1576020820181803683370190505b509050600360fc1b816000815181106133fc576133fc614102565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061342b5761342b614102565b60200101906001600160f81b031916908160001a905350600061344f84600261499c565b61345a9060016140ef565b90505b60018111156134d2576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061348e5761348e614102565b1a60f81b8282815181106134a4576134a4614102565b60200101906001600160f81b031916908160001a90535060049490941c936134cb816149b3565b905061345d565b5083156104865760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610430565b61352a8161358e565b15610d6157815460ff19166002178255600080613546836135a8565b9150915083600101547fe134987599ae266ec90edeff1b26125b287dbb57b10822649432d1bb26537fba83836040516135809291906149ca565b60405180910390a250505050565b600081602001516000148061048957505060200151461490565b6060806135b48361358e565b61360c5760405162461bcd60e51b815260206004820152602360248201527f50726f706f73616c3a20717565727920666f7220696e76616c696420636861696044820152621b925960ea1b6064820152608401610430565b8260600151516001600160401b0381111561362957613629613ebe565b604051908082528060200260200182016040528015613652578160200160208202803683370190505b5091508260600151516001600160401b0381111561367257613672613ebe565b6040519080825280602002602001820160405280156136a557816020015b60608152602001906001900390816136905790505b50905060005b836060015151811015613845578360c0015181815181106136ce576136ce614102565b60200260200101515a116137245760405162461bcd60e51b815260206004820152601a60248201527f50726f706f73616c3a20696e73756666696369656e74206761730000000000006044820152606401610430565b8360600151818151811061373a5761373a614102565b60200260200101516001600160a01b03168460800151828151811061376157613761614102565b60200260200101518560c00151838151811061377f5761377f614102565b6020026020010151908660a00151848151811061379e5761379e614102565b60200260200101516040516137b391906141ca565b600060405180830381858888f193505050503d80600081146137f1576040519150601f19603f3d011682016040523d82523d6000602084013e6137f6565b606091505b5084838151811061380957613809614102565b6020026020010184848151811061382257613822614102565b6020908102919091010191909152901515905261383e81614118565b90506136ab565b50915091565b6040518060e00160405280600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b50805460008255906000526020600020908101906105aa91905b808211156138b657600081556001016138a2565b5090565b60008083601f8401126138cc57600080fd5b5081356001600160401b038111156138e357600080fd5b6020830191508360208260051b85010111156138fe57600080fd5b9250929050565b60008083601f84011261391757600080fd5b5081356001600160401b0381111561392e57600080fd5b6020830191508360206060830285010111156138fe57600080fd5b60008060008060006060868803121561396157600080fd5b85356001600160401b038082111561397857600080fd5b9087019060e0828a03121561398c57600080fd5b909550602087013590808211156139a257600080fd5b6139ae89838a016138ba565b909650945060408801359150808211156139c757600080fd5b506139d488828901613905565b969995985093965092949392505050565b6001600160a01b03811681146105aa57600080fd5b60008060408385031215613a0d57600080fd5b823591506020830135613a1f816139e5565b809150509250929050565b600080600080600080600080600060a08a8c031215613a4857600080fd5b8935985060208a01356001600160401b0380821115613a6657600080fd5b613a728d838e016138ba565b909a50985060408c0135915080821115613a8b57600080fd5b613a978d838e016138ba565b909850965060608c0135915080821115613ab057600080fd5b613abc8d838e016138ba565b909650945060808c0135915080821115613ad557600080fd5b50613ae28c828d016138ba565b915080935050809150509295985092959850929598565b600060208284031215613b0b57600080fd5b8135610486816139e5565b60008060408385031215613b2957600080fd5b50508035926020909101359150565b634e487b7160e01b600052602160045260246000fd5b600281106105aa576105aa613b38565b600081518084526020808501945080840160005b83811015613ba7578151805160ff16885283810151848901526040908101519088015260609096019590820190600101613b72565b509495945050505050565b604080825283519082018190526000906020906060840190828701845b82811015613bf4578151613be281613b4e565b84529284019290840190600101613bcf565b50505083810382850152613c088186613b5e565b9695505050505050565b600080600060608486031215613c2757600080fd5b83359250602084013591506040840135613c40816139e5565b809150509250925092565b600060208284031215613c5d57600080fd5b5035919050565b600080600080600060608688031215613c7c57600080fd5b85356001600160401b0380821115613c9357600080fd5b9087019060c0828a03121561398c57600080fd5b600080600060408486031215613cbc57600080fd5b8335925060208401356001600160401b03811115613cd957600080fd5b613ce5868287016138ba565b9497909650939450505050565b6020815260006104866020830184613b5e565b600080600080600060608688031215613d1d57600080fd5b8535945060208601356001600160401b03808211156139a257600080fd5b60008060408385031215613d4e57600080fd5b8235613d59816139e5565b91506020830135613a1f816139e5565b60008060008060008060008060008060c08b8d031215613d8857600080fd5b8a35995060208b0135985060408b01356001600160401b0380821115613dad57600080fd5b613db98e838f016138ba565b909a50985060608d0135915080821115613dd257600080fd5b613dde8e838f016138ba565b909850965060808d0135915080821115613df757600080fd5b613e038e838f016138ba565b909650945060a08d0135915080821115613e1c57600080fd5b50613e298d828e016138ba565b915080935050809150509295989b9194979a5092959850565b60a0810160048710613e5657613e56613b38565b95815260208101949094526040840192909252606083015260809091015290565b60208082526027908201527f476f7665726e616e636541646d696e3a2073656e646572206973206e6f74206760408201526637bb32b93737b960c91b606082015260800190565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b0381118282101715613ef657613ef6613ebe565b60405290565b60405160c081016001600160401b0381118282101715613ef657613ef6613ebe565b604051601f8201601f191681016001600160401b0381118282101715613f4657613f46613ebe565b604052919050565b60006001600160401b03821115613f6757613f67613ebe565b5060051b60200190565b6000613f84613f7f84613f4e565b613f1e565b8381529050602080820190600585901b840186811115613fa357600080fd5b845b818110156140365780356001600160401b0380821115613fc55760008081fd5b8188019150601f8a81840112613fdb5760008081fd5b823582811115613fed57613fed613ebe565b613ffe818301601f19168801613f1e565b92508083528b8782860101111561401757600091508182fd5b8087850188850137600090830187015250855250928201928201613fa5565b505050509392505050565b6000610486368484613f71565b60208082526027908201527f476f7665726e616e636541646d696e3a206f6e6c7920616c6c6f7765642073656040820152661b198b58d85b1b60ca1b606082015260800190565b60208082526024908201527f476f7665726e616e636541646d696e3a2073657420746f206e6f6e2d636f6e746040820152631c9858dd60e21b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b80820180821115610489576104896140d9565b634e487b7160e01b600052603260045260246000fd5b60006001820161412a5761412a6140d9565b5060010190565b60006020828403121561414357600080fd5b8151610486816139e5565b83815260406020808301829052908201839052600090849060608401835b8681101561419a57833561417f816139e5565b6001600160a01b03168252928201929082019060010161416c565b50979650505050505050565b60005b838110156141c15781810151838201526020016141a9565b50506000910152565b600082516141dc8184602087016141a6565b9190910192915050565b600081518084526141fe8160208601602086016141a6565b601f01601f19169290920160200192915050565b60208152600061048660208301846141e6565b60006020828403121561423757600080fd5b5051919050565b600082601f83011261424f57600080fd5b8135602061425f613f7f83613f4e565b82815260059290921b8401810191818101908684111561427e57600080fd5b8286015b848110156142a2578035614295816139e5565b8352918301918301614282565b509695505050505050565b600082601f8301126142be57600080fd5b813560206142ce613f7f83613f4e565b82815260059290921b840181019181810190868411156142ed57600080fd5b8286015b848110156142a257803583529183019183016142f1565b600082601f83011261431957600080fd5b61048683833560208501613f71565b600060e0823603121561433a57600080fd5b614342613ed4565b82358152602083013560208201526040830135604082015260608301356001600160401b038082111561437457600080fd5b6143803683870161423e565b6060840152608085013591508082111561439957600080fd5b6143a5368387016142ad565b608084015260a08501359150808211156143be57600080fd5b6143ca36838701614308565b60a084015260c08501359150808211156143e357600080fd5b506143f0368286016142ad565b60c08301525092915050565b600081518084526020808501945080840160005b83811015613ba757815187529582019590820190600101614410565b600081518084526020808501808196508360051b8101915082860160005b858110156144745782840389526144628483516141e6565b9885019893509084019060010161444a565b5091979650505050505050565b600060e08301825184526020808401518186015260408401516040860152606084015160e06060870152828151808552610100880191508383019450600092505b808310156144eb5784516001600160a01b031682529383019360019290920191908301906144c2565b5060808601519350868103608088015261450581856143fc565b935050505060a083015184820360a0860152614521828261442c565b91505060c083015184820360c086015261453b82826143fc565b95945050505050565b6080815260006145576080830187614481565b60208681850152838203604085015260c08201865183528187015182840152604087015160c0604085015281815180845260e0860191508483019350600092505b808310156145c15783516145ab81613b4e565b8252928401926001929092019190840190614598565b506060890151935084810360608601526145db81856143fc565b9350505050608086015182820360808401526145f7828261442c565b91505060a086015182820360a084015261461182826143fc565b935050505061453b60608301846001600160a01b03169052565b6020808252602f908201527f476f7665726e616e636541646d696e3a206361737420766f746520666f72206960408201526e1b9d985b1a59081c1c9bdc1bdcd85b608a1b606082015260800190565b600281106105aa57600080fd5b600082601f83011261469857600080fd5b813560206146a8613f7f83613f4e565b82815260059290921b840181019181810190868411156146c757600080fd5b8286015b848110156142a25780356146de8161467a565b83529183019183016146cb565b600060c082360312156146fd57600080fd5b614705613efc565b823581526020830135602082015260408301356001600160401b038082111561472d57600080fd5b61473936838701614687565b6040840152606085013591508082111561475257600080fd5b61475e368387016142ad565b6060840152608085013591508082111561477757600080fd5b61478336838701614308565b608084015260a085013591508082111561479c57600080fd5b506147a9368286016142ad565b60a08301525092915050565b6000606082840312156147c757600080fd5b604051606081018181106001600160401b03821117156147e9576147e9613ebe565b604052823560ff811681146147fd57600080fd5b8152602083810135908201526040928301359281019290925250919050565b60408152600061482f6040830185614481565b905060018060a01b03831660208301529392505050565b60208082526026908201527f436f7265476f7665726e616e63653a20696e76616c69642070726f706f73616c604082015265206e6f6e636560d01b606082015260800190565b83815260208101839052606081016148a383613b4e565b826040830152949350505050565b81810381811115610489576104896140d9565b6000602082840312156148d657600080fd5b81356104868161467a565b73024b9b7b630ba32b223b7bb32b93730b731b29d160651b8152600082516149108160148501602087016141a6565b6d08185b1c9958591e481d9bdd195960921b6014939091019283015250602201919050565b6f021b7b932a3b7bb32b93730b731b29d160851b8152600082516149608160108501602087016141a6565b6d08185b1c9958591e481d9bdd195960921b6010939091019283015250601e01919050565b6040810161499284613b4e565b9281526020015290565b8082028115828204841417610489576104896140d9565b6000816149c2576149c26140d9565b506000190190565b604080825283519082018190526000906020906060840190828701845b82811015614a055781511515845292840192908401906001016149e7565b50505083810382850152613c08818661442c56fef8704f8860d9e985bf6c52ec4738bd10fe31487599b36c0944f746ea09dc256ba2646970667358221220b8c44859a99fef98140e7036521676f05098a664fa30b41b44982148a6a7162764736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101725760003560e01c80633644e515116100de578063a1819f9a11610097578063bc96180b11610071578063bc96180b146103c9578063cd596583146103d1578063f3b7dead146103e2578063fb4f6371146103f557600080fd5b8063a1819f9a14610348578063b384abef1461035b578063b5e337de146103b657600080fd5b80633644e515146102c05780635511cde1146102d557806356e237e8146102e65780637eff275e146102f9578063988ef53c1461030c5780639a7d33821461033557600080fd5b8063204e1c7a11610130578063204e1c7a1461020e5780632c5e6520146102395780632e96a6fb1461024c5780632faf925d1461025f578063332635be1461027257806334d5f37b1461029257600080fd5b80624054b814610177578063055c68891461018c57806309fcd8c7146101b45780630b26cf66146101c75780630b881830146101da5780631c905e39146101ed575b600080fd5b61018a610185366004613949565b610408565b005b61019f61019a3660046139fa565b61045d565b60405190151581526020015b60405180910390f35b61018a6101c2366004613a2a565b61048f565b61018a6101d5366004613af9565b610558565b61018a6101e8366004613949565b6105ad565b6102006101fb366004613b16565b6105c9565b6040516101ab929190613bb2565b61022161021c366004613af9565b6108c7565b6040516001600160a01b0390911681526020016101ab565b61019f610247366004613c12565b6109b9565b61018a61025a366004613c4b565b6109ef565b61018a61026d366004613c64565b610a17565b610285610280366004613ca7565b610a51565b6040516101ab9190613cf2565b6102b26102a0366004613c4b565b60006020819052908152604090205481565b6040519081526020016101ab565b6102b2600080516020614a1a83398151915281565b6003546001600160a01b0316610221565b61018a6102f4366004613d05565b610b82565b61018a610307366004613d3b565b610c26565b6102b261031a366004613af9565b6001600160a01b031660009081526007602052604090205490565b61018a610343366004613b16565b610d57565b61018a610356366004613d69565b610d65565b6103a5610369366004613b16565b600160208181526000938452604080852090915291835291208054918101546002820154600383015460069093015460ff909416939192909185565b6040516101ab959493929190613e42565b61018a6103c4366004613af9565b610e4b565b6102b2610e9d565b6004546001600160a01b0316610221565b6102216103f0366004613af9565b610ead565b61018a610403366004613c64565b610f7a565b600061041333610fdd565b116104395760405162461bcd60e51b815260040161043090613e77565b60405180910390fd5b6104568585858585600080516020614a1a83398151915233611151565b5050505050565b60008281526006602090815260408083206001600160a01b038516845260020190915281205415155b90505b92915050565b600061049a33610fdd565b116104b75760405162461bcd60e51b815260040161043090613e77565b61054c8989898989808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506104fd92508a91508b9050614041565b87878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061053a9250610b73915050565b6004546001600160a01b0316336111bb565b50505050505050505050565b3330146105775760405162461bcd60e51b81526004016104309061404e565b6000816001600160a01b03163b116105a15760405162461bcd60e51b815260040161043090614095565b6105aa816112f0565b50565b6104568585858585600080516020614a1a833981519152611345565b600082815260016020908152604080832084845290915281206004810154600582015460609384939291906105fe82846140ef565b9050806001600160401b0381111561061857610618613ebe565b604051908082528060200260200182016040528015610641578160200160208202803683370190505b509550806001600160401b0381111561065c5761065c613ebe565b6040519080825280602002602001820160405280156106a757816020015b604080516060810182526000808252602080830182905292820152825260001990920191018161067a5790505b50945060005b838110156107aa5760008782815181106106c9576106c9614102565b602002602001019060018111156106e2576106e2613b38565b908160018111156106f5576106f5613b38565b90525060008981526001602090815260408083208b84529091528120600487018054600790920192918490811061072e5761072e614102565b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815460ff1681526001820154938101939093526002015490820152865187908390811061078c5761078c614102565b602002602001018190525080806107a290614118565b9150506106ad565b5060005b828110156108bb576001876107c386846140ef565b815181106107d3576107d3614102565b602002602001019060018111156107ec576107ec613b38565b908160018111156107ff576107ff613b38565b90525060008981526001602090815260408083208b84529091528120600587018054600790920192918490811061083857610838614102565b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815460ff16815260018201549381019390935260020154908201528661088d86846140ef565b8151811061089d5761089d614102565b602002602001018190525080806108b390614118565b9150506107ae565b50505050509250929050565b6000806000836001600160a01b03166040516108ed90635c60da1b60e01b815260040190565b600060405180830381855afa9150503d8060008114610928576040519150601f19603f3d011682016040523d82523d6000602084013e61092d565b606091505b50915091508161099d5760405162461bcd60e51b815260206004820152603560248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c2060696d706044820152741b195b595b9d185d1a5bdb8a0a580819985a5b1959605a1b6064820152608401610430565b808060200190518101906109b19190614131565b949350505050565b600083815260016020818152604080842086855282528084206001600160a01b03861685526007019091528220015415156109b1565b333014610a0e5760405162461bcd60e51b81526004016104309061404e565b6105aa81600255565b6104568585858585600080516020614a1a833981519152610a406003546001600160a01b031690565b6004546001600160a01b03166113cc565b6060816001600160401b03811115610a6b57610a6b613ebe565b604051908082528060200260200182016040528015610ab657816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181610a895790505b50905060005b82811015610b6b57600085815260086020526040812090858584818110610ae557610ae5614102565b9050602002016020810190610afa9190613af9565b6001600160a01b0316815260208082019290925260409081016000208151606081018352815460ff16815260018201549381019390935260020154908201528251839083908110610b4d57610b4d614102565b60200260200101819052508080610b6390614118565b915050610abc565b509392505050565b6003546001600160a01b031690565b610ba68484848489610b92611480565b600080516020614a1a8339815191526115ec565b60008581526006602052604090206001815460ff166003811115610bcc57610bcc613b38565b03610c1e5760058690556040517f1599b04a1104d19ef534dc177f3de0164ef5e4b99fad7485eda134600fca5f0290610c0a9088908890889061414e565b60405180910390a1805460ff191660021781555b505050505050565b333014610c455760405162461bcd60e51b81526004016104309061404e565b604080516001600160a01b0383811660248084019190915283518084039091018152604490920183526020820180516001600160e01b03166308f2839760e41b1790529151600092851691610c99916141ca565b6000604051808303816000865af19150503d8060008114610cd6576040519150601f19603f3d011682016040523d82523d6000602084013e610cdb565b606091505b5050905080610d525760405162461bcd60e51b815260206004820152603960248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c206063686160448201527f6e676541646d696e28616464726573732960206661696c6564000000000000006064820152608401610430565b505050565b610d618282611924565b5050565b6000610d7033610fdd565b11610d8d5760405162461bcd60e51b815260040161043090613e77565b610e3e8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c918291850190849080828437600092019190915250610e0392508a91508b9050614041565b87878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525033925061194c915050565b5050505050505050505050565b333014610e6a5760405162461bcd60e51b81526004016104309061404e565b6000816001600160a01b03163b11610e945760405162461bcd60e51b815260040161043090614095565b6105aa81611a64565b6000610ea860025490565b905090565b6000806000836001600160a01b0316604051610ed3906303e1469160e61b815260040190565b600060405180830381855afa9150503d8060008114610f0e576040519150601f19603f3d011682016040523d82523d6000602084013e610f13565b606091505b50915091508161099d5760405162461bcd60e51b815260206004820152602c60248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c206061646d60448201526b1a5b8a0a580819985a5b195960a21b6064820152608401610430565b6000610f8533610fdd565b11610fa25760405162461bcd60e51b815260040161043090613e77565b610c1e8585858585600080516020614a1a833981519152610fcb6003546001600160a01b031690565b6004546001600160a01b031633611ab2565b6000806000610ff46003546001600160a01b031690565b604080516001600160a01b03878116602480840191909152835180840382018152604490930184526020830180516001600160e01b0316631af0725f60e31b1790529251931692634bb5274a9261104c929101614212565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161108591906141ca565b600060405180830381855afa9150503d80600081146110c0576040519150601f19603f3d011682016040523d82523d6000602084013e6110c5565b606091505b50915091508161113d5760405162461bcd60e51b815260206004820152603f60248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c206067657460448201527f476f7665726e6f7257656967687428616464726573732960206661696c6564006064820152608401610430565b808060200190518101906109b19190614225565b61116361115d88614328565b82611b15565b50600061117761117289614328565b611bfd565b90506111b161118589614328565b8888888861119d89611198896000611d9c565b611df2565b6111ac8a6111988a6001611d9c565b611e19565b5050505050505050565b6040805160c08101909152600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5549091829181906112039060016140ef565b81526020018c81526020018b8b808060200260200160405190810160405280939291908181526020018383602002808284376000920182905250938552505050602082018b9052604082018a90526060909101889052909150611267828787612172565b905061127e6002548261233890919063ffffffff16565b600061128982611bfd565b90506112976000828f612434565b935080847f771d78ae9e5fca95a532fb0971d575d0ce9b59d14823c063e08740137e0e0eca846112c687612562565b878a6040516112d89493929190614544565b60405180910390a35050509998505050505050505050565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5cbd8a0bb00196365d5eb3457c6734e7f06666c3c78e5469b4c9deec7edae048906020015b60405180910390a150565b600061135361117288614328565b6020808901356000908152600180835260408083208c358452909352919020015490915081146113955760405162461bcd60e51b81526004016104309061462b565b6113c36113a188614328565b878787876113b488611198896000611d9c565b6111ac896111988a6001611d9c565b50505050505050565b60006113e383836113dc8c6146eb565b9190612172565b905060006113f86113f38b6146eb565b612562565b905061140382611bfd565b600080805260016020818152855183527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb499052604090912001541461145a5760405162461bcd60e51b81526004016104309061462b565b61054c828a8a8a8a6114718b611198896000611d9c565b6111ac8c6111988a6001611d9c565b60008060006114976003546001600160a01b031690565b6040805160048152602480820183526020820180516001600160e01b0316637de5dedd60e01b17905291516001600160a01b039390931692634bb5274a926114e0929101614212565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161151991906141ca565b600060405180830381855afa9150503d8060008114611554576040519150601f19603f3d011682016040523d82523d6000602084013e611559565b606091505b5091509150816115d15760405162461bcd60e51b815260206004820152603860248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c20606d696e60448201527f696d756d566f7465576569676874282960206661696c656400000000000000006064820152608401610430565b808060200190518101906115e59190614225565b9250505090565b6005548310156116575760405162461bcd60e51b815260206004820152603060248201527f424f73476f7665726e616e636550726f706f73616c3a20717565727920666f7260448201526f081bdd5d19185d1959081c195c9a5bd960821b6064820152608401610430565b851580159061166557508315155b6116c55760405162461bcd60e51b815260206004820152602b60248201527f424f73476f7665726e616e636550726f706f73616c3a20696e76616c6964206160448201526a0e4e4c2f240d8cadccee8d60ab1b6064820152608401610430565b60408051606081018252600080825260208201819052918101919091526000806000611724878c8c808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506126bc92505050565b905060006117328683611df2565b6000898152600660205260408120919250805b8b8110156118b4578c8c8281811061175f5761175f614102565b90506060020180360381019061177591906147b5565b975061178f8489600001518a602001518b6040015161271d565b9650866001600160a01b0316866001600160a01b0316106117fe5760405162461bcd60e51b8152602060048201526024808201527f424f73476f7665726e616e636550726f706f73616c3a20696e76616c6964206f604482015263393232b960e11b6064820152608401610430565b869550600061180c88612745565b905080156118a1576001600160a01b03881660008181526007602090815260408083204390558f835260088252808320938352928152908290208b51815460ff191660ff909116178155908b0151600180830191909155918b015160029091015592508261187d858a848f8b6128b0565b600381111561188e5761188e613b38565b036118a1575050505050505050506113c3565b50806118ac81614118565b915050611745565b50806119145760405162461bcd60e51b815260206004820152602960248201527f424f73476f7665726e616e636550726f706f73616c3a20696e76616c6964207360448201526869676e61747572657360b81b6064820152608401610430565b5050505050505050505050505050565b60008281526001602090815260408083208484529091529020611946816129ac565b50505050565b60008760000361199e5760405162461bcd60e51b815260206004820181905260248201527f436f7265476f7665726e616e63653a20696e76616c696420636861696e2069646044820152606401610430565b6040805160e08101825260008a815260208190529182205481906119c39060016140ef565b81526020018a8152602001898152602001888152602001878152602001868152602001858152509050611a016002548261233890919063ffffffff16565b6000611a0c82611bfd565b9050611a198a828b612434565b925080838b7fa57d40f1496988cf60ab7c9d5ba4ff83647f67d3898d441a3aaf21b651678fd98588604051611a4f92919061481c565b60405180910390a45050979650505050505050565b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527ffd6f5f93d69a07c593a09be0b208bff13ab4ffd6017df3b33433d63bdc59b4d79060200161133a565b611aba61384b565b611ace611ac68b6146eb565b858585612b18565b5090506000611adf6113f38c6146eb565b9050611b07828b8b8b8b611af88c611198896000611d9c565b6111ac8d6111988a6001611d9c565b509998505050505050505050565b6020820151600090808203611b6c5760405162461bcd60e51b815260206004820181905260248201527f436f7265476f7665726e616e63653a20696e76616c696420636861696e2069646044820152606401610430565b600254611b7a908590612338565b6000611b8585611bfd565b9050611b9682828760400151612434565b85519093508314611bb95760405162461bcd60e51b815260040161043090614846565b8083837fa57d40f1496988cf60ab7c9d5ba4ff83647f67d3898d441a3aaf21b651678fd98888604051611bed92919061481c565b60405180910390a4505092915050565b6000806000806000808660800151905060008760600151905060008860a00151516001600160401b03811115611c3557611c35613ebe565b604051908082528060200260200182016040528015611c5e578160200160208202803683370190505b5060c08a015190915060005b8251811015611cc7578a60a001518181518110611c8957611c89614102565b602002602001015180519060200120838281518110611caa57611caa614102565b602090810291909101015280611cbf81614118565b915050611c6a565b506020835102602084012097506020845102602085012096506020825102602083012095506020815102602082012094507fd051578048e6ff0bbc9fca3b65a42088dbde10f36ca841de566711087ad9b08a60001b8a600001518b602001518c604001518b8b8b8b604051602001611d77989796959493929190978852602088019690965260408701949094526060860192909252608085015260a084015260c083015260e08201526101000190565b6040516020818303038152906040528051906020012098505050505050505050919050565b604051600090611dd4907fd900570327c4c0df8dd6bdd522b7da7e39145dd049d2fd4602276adcd511e3c2908590859060200161488c565b60405160208183030381529060405280519060200120905092915050565b60405161190160f01b60208201526022810183905260428101829052600090606201611dd4565b8415801590611e2757508483145b611e845760405162461bcd60e51b815260206004820152602860248201527f476f7665726e616e636550726f706f73616c3a20696e76616c696420617272616044820152670f240d8cadccee8d60c31b6064820152608401610430565b6000611e8e611480565b9050600081611e9b612bd5565b611ea591906148b1565b611eb09060016140ef565b9050600080611ed8604080516060810182526000808252602082018190529181019190915290565b6000805b89811015612106578a8a82818110611ef657611ef6614102565b905060600201803603810190611f0c91906147b5565b925060008d8d83818110611f2257611f22614102565b9050602002016020810190611f3791906148c4565b6001811115611f4857611f48613b38565b03611f6c57611f658984600001518560200151866040015161271d565b9350612027565b60018d8d83818110611f8057611f80614102565b9050602002016020810190611f9591906148c4565b6001811115611fa657611fa6613b38565b03611fc357611f658884600001518560200151866040015161271d565b60405162461bcd60e51b815260206004820152603360248201527f476f7665726e616e636550726f706f73616c3a20717565727920666f7220756e604482015272737570706f7274656420766f7465207479706560681b6064820152608401610430565b836001600160a01b0316856001600160a01b0316106120925760405162461bcd60e51b815260206004820152602160248201527f476f7665726e616e636550726f706f73616c3a20696e76616c6964206f7264656044820152603960f91b6064820152608401610430565b83945060006120a085610fdd565b905080156120f357600192506120e18f8f8f858181106120c2576120c2614102565b90506020020160208101906120d791906148c4565b8a8a898987612d1c565b156120f35750505050505050506113c3565b50806120fe81614118565b915050611edc565b50806121635760405162461bcd60e51b815260206004820152602660248201527f476f7665726e616e636550726f706f73616c3a20696e76616c6964207369676e60448201526561747572657360d01b6064820152608401610430565b50505050505050505050505050565b61217a61384b565b83518152602080850151604080840191909152600091830191909152840151516001600160401b038111156121b1576121b1613ebe565b6040519080825280602002602001820160405280156121da578160200160208202803683370190505b5060608083019190915284015160808083019190915284015160a08083019190915284015160c082015260005b846040015151811015610b6b5760018560400151828151811061222c5761222c614102565b6020026020010151600181111561224557612245613b38565b0361228657828260600151828151811061226157612261614102565b60200260200101906001600160a01b031690816001600160a01b031681525050612326565b60008560400151828151811061229e5761229e614102565b602002602001015160018111156122b7576122b7613b38565b036122d357838260600151828151811061226157612261614102565b60405162461bcd60e51b815260206004820152602260248201527f476c6f62616c50726f706f73616c3a20756e737570706f727465642074617267604482015261195d60f21b6064820152608401610430565b8061233081614118565b915050612207565b60008260600151511180156123565750816080015151826060015151145b801561236b57508160a0015151826060015151145b801561238057508160c0015151826060015151145b6123cc5760405162461bcd60e51b815260206004820152601e60248201527f50726f706f73616c3a20696e76616c6964206172726179206c656e67746800006044820152606401610430565b6123d681426140ef565b82604001511115610d615760405162461bcd60e51b815260206004820152602260248201527f50726f706f73616c3a20696e76616c6964206578706972792074696d6573746160448201526106d760f41b6064820152608401610430565b6000838152602081905260408120549081900361246557506000838152602081905260409020600190819055612535565b6000848152600160209081526040808320848452909152812090612488826129ac565b905080612532576000825460ff1660038111156124a7576124a7613b38565b0361250e5760405162461bcd60e51b815260206004820152603160248201527f436f7265476f7665726e616e63653a2063757272656e742070726f706f73616c604482015270081a5cc81b9bdd0818dbdb5c1b195d1959607a1b6064820152608401610430565b6000868152602081905260408120805490919061252a90614118565b918290555092505b50505b60009384526001602081815260408087208488529091529094209384019290925560069092019190915590565b6000806000806000808660600151905060008760400151905060008860800151516001600160401b0381111561259a5761259a613ebe565b6040519080825280602002602001820160405280156125c3578160200160208202803683370190505b5060a08a015190915060005b825181101561262c578a6080015181815181106125ee576125ee614102565b60200260200101518051906020012083828151811061260f5761260f614102565b60209081029190910101528061262481614118565b9150506125cf565b5082516020908102848201208551820286830120845183028584012084518402858501208e518f860151604080517f1463f426c05aff2c1a7a0957a71c9898bc8b47142540538e79ee25ee911413509881019890985287019190915260608601526080850184905260a0850183905260c0850182905260e08501819052929b509099509750955061010001611d77565b8051602090810291810191909120604080517feea5e3908ac28cbdbbce8853e49444c558a0a03597e98ef19e6ff86162ed9ae38185015280820194909452606080850192909252805180850390920182526080909301909252815191012090565b600080600061272e878787876130e3565b9150915061273b816131d0565b5095945050505050565b600080600061275c6003546001600160a01b031690565b604080516001600160a01b03878116602480840191909152835180840382018152604490930184526020830180516001600160e01b0316635624191160e01b1790529251931692634bb5274a926127b4929101614212565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516127ed91906141ca565b600060405180830381855afa9150503d8060008114612828576040519150601f19603f3d011682016040523d82523d6000602084013e61282d565b606091505b50915091508161113d5760405162461bcd60e51b815260206004820152604260248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c206067657460448201527f427269646765566f74657257656967687428616464726573732960206661696c606482015261195960f21b608482015260a401610430565b6001600160a01b03841660009081526002860160205260408120541561291a576128e4856001600160a01b03166014613386565b6040516020016128f491906148e1565b60408051601f198184030181529082905262461bcd60e51b825261043091600401614212565b6001600160a01b03851660009081526002870160209081526040808320859055848352600389019091528120805486919083906129589084906140ef565b925050819055905083811015801561298557506000875460ff16600381111561298357612983613b38565b145b1561299d57865460ff19166001908117885587018390555b5050935460ff16949350505050565b60068101544210801590612b135760018201546040517f58f98006a7f2f253f8ae8f8b7cec9008ca05359633561cd7c22f3005682d4a5590600090a260005b6004830154811015612a5b57826007016000846004018381548110612a1257612a12614102565b60009182526020808320909101546001600160a01b031683528201929092526040018120805460ff19168155600181018290556002015580612a5381614118565b9150506129eb565b5060005b6005830154811015612acf57826007016000846005018381548110612a8657612a86614102565b60009182526020808320909101546001600160a01b031683528201929092526040018120805460ff19168155600181018290556002015580612ac781614118565b915050612a5f565b50815460ff191682556000600183018190556002830181905560038301819055612afd906004840190613888565b612b0b600583016000613888565b600060068301555b919050565b612b2061384b565b6000612b2d868686612172565b9150612b446002548361233890919063ffffffff16565b6000612b4f83611bfd565b9050612b616000828960200151612434565b83519092508214612b845760405162461bcd60e51b815260040161043090614846565b80827f771d78ae9e5fca95a532fb0971d575d0ce9b59d14823c063e08740137e0e0eca85612bb18b612562565b8b89604051612bc39493929190614544565b60405180910390a35094509492505050565b6000806000612bec6003546001600160a01b031690565b6040805160048152602480820183526020820180516001600160e01b031663926323d560e01b17905291516001600160a01b039390931692634bb5274a92612c35929101614212565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051612c6e91906141ca565b600060405180830381855afa9150503d8060008114612ca9576040519150601f19603f3d011682016040523d82523d6000602084013e612cae565b606091505b5091509150816115d15760405162461bcd60e51b815260206004820152603360248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c2060746f74604482015272185b15d95a59da1d1cca0a580819985a5b1959606a1b6064820152608401610430565b60208088015188516000828152600184526040808220838352909452928320612d44816129ac565b15612d5557600193505050506130d8565b6020808c015160009081529081905260409020548214612dd05760405162461bcd60e51b815260206004820152603060248201527f436f7265476f7665726e616e63653a20717565727920666f7220696e76616c6960448201526f642070726f706f73616c206e6f6e636560801b6064820152608401610430565b6000815460ff166003811115612de857612de8613b38565b14612e435760405162461bcd60e51b815260206004820152602560248201527f436f7265476f7665726e616e63653a2074686520766f74652069732066696e616044820152641b1a5e995960da1b6064820152608401610430565b6001600160a01b038716600090815260078201602052604090206001015415612e8a57612e7a876001600160a01b03166014613386565b6040516020016128f49190614935565b6001600160a01b03871660008181526007830160209081526040918290208951815460ff191660ff909116178155908901516001808301919091558983015160029092019190915583015490517f1203f9e81c814a35f5f4cc24087b2a24c6fb7986a9f1406b68a9484882c93a2390612f06908e908a90614985565b60405180910390a3600080808c6001811115612f2457612f24613b38565b03612f79576004830180546001810182556000918252602082200180546001600160a01b0319166001600160a01b038c16179055600384018054899290612f6c9084906140ef565b9250508190559150613038565b60018c6001811115612f8d57612f8d613b38565b03612fe2576005830180546001810182556000918252602082200180546001600160a01b0319166001600160a01b038c16179055600284018054899290612fd59084906140ef565b9250508190559050613038565b60405162461bcd60e51b815260206004820152602560248201527f436f7265476f7665726e616e63653a20756e737570706f7274656420766f7465604482015264207479706560d81b6064820152608401610430565b8a821061308c57825460ff19166001908117845580840154604051919750907f5c819725ea53655a3b898f3df59b66489761935454e9212ca1e5ebd759953d0b90600090a2613087838e613521565b6130d2565b8981106130d257825460ff19166003178355600180840154604051919750907f55295d4ce992922fa2e5ffbf3a3dcdb367de0a15e125ace083456017fd22060f90600090a25b50505050505b979650505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561311a57506000905060036131c7565b8460ff16601b1415801561313257508460ff16601c14155b1561314357506000905060046131c7565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613197573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166131c0576000600192509250506131c7565b9150600090505b94509492505050565b60008160048111156131e4576131e4613b38565b036131ec5750565b600181600481111561320057613200613b38565b0361324d5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610430565b600281600481111561326157613261613b38565b036132ae5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610430565b60038160048111156132c2576132c2613b38565b0361331a5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610430565b600481600481111561332e5761332e613b38565b036105aa5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610430565b6060600061339583600261499c565b6133a09060026140ef565b6001600160401b038111156133b7576133b7613ebe565b6040519080825280601f01601f1916602001820160405280156133e1576020820181803683370190505b509050600360fc1b816000815181106133fc576133fc614102565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061342b5761342b614102565b60200101906001600160f81b031916908160001a905350600061344f84600261499c565b61345a9060016140ef565b90505b60018111156134d2576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061348e5761348e614102565b1a60f81b8282815181106134a4576134a4614102565b60200101906001600160f81b031916908160001a90535060049490941c936134cb816149b3565b905061345d565b5083156104865760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610430565b61352a8161358e565b15610d6157815460ff19166002178255600080613546836135a8565b9150915083600101547fe134987599ae266ec90edeff1b26125b287dbb57b10822649432d1bb26537fba83836040516135809291906149ca565b60405180910390a250505050565b600081602001516000148061048957505060200151461490565b6060806135b48361358e565b61360c5760405162461bcd60e51b815260206004820152602360248201527f50726f706f73616c3a20717565727920666f7220696e76616c696420636861696044820152621b925960ea1b6064820152608401610430565b8260600151516001600160401b0381111561362957613629613ebe565b604051908082528060200260200182016040528015613652578160200160208202803683370190505b5091508260600151516001600160401b0381111561367257613672613ebe565b6040519080825280602002602001820160405280156136a557816020015b60608152602001906001900390816136905790505b50905060005b836060015151811015613845578360c0015181815181106136ce576136ce614102565b60200260200101515a116137245760405162461bcd60e51b815260206004820152601a60248201527f50726f706f73616c3a20696e73756666696369656e74206761730000000000006044820152606401610430565b8360600151818151811061373a5761373a614102565b60200260200101516001600160a01b03168460800151828151811061376157613761614102565b60200260200101518560c00151838151811061377f5761377f614102565b6020026020010151908660a00151848151811061379e5761379e614102565b60200260200101516040516137b391906141ca565b600060405180830381858888f193505050503d80600081146137f1576040519150601f19603f3d011682016040523d82523d6000602084013e6137f6565b606091505b5084838151811061380957613809614102565b6020026020010184848151811061382257613822614102565b6020908102919091010191909152901515905261383e81614118565b90506136ab565b50915091565b6040518060e00160405280600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b50805460008255906000526020600020908101906105aa91905b808211156138b657600081556001016138a2565b5090565b60008083601f8401126138cc57600080fd5b5081356001600160401b038111156138e357600080fd5b6020830191508360208260051b85010111156138fe57600080fd5b9250929050565b60008083601f84011261391757600080fd5b5081356001600160401b0381111561392e57600080fd5b6020830191508360206060830285010111156138fe57600080fd5b60008060008060006060868803121561396157600080fd5b85356001600160401b038082111561397857600080fd5b9087019060e0828a03121561398c57600080fd5b909550602087013590808211156139a257600080fd5b6139ae89838a016138ba565b909650945060408801359150808211156139c757600080fd5b506139d488828901613905565b969995985093965092949392505050565b6001600160a01b03811681146105aa57600080fd5b60008060408385031215613a0d57600080fd5b823591506020830135613a1f816139e5565b809150509250929050565b600080600080600080600080600060a08a8c031215613a4857600080fd5b8935985060208a01356001600160401b0380821115613a6657600080fd5b613a728d838e016138ba565b909a50985060408c0135915080821115613a8b57600080fd5b613a978d838e016138ba565b909850965060608c0135915080821115613ab057600080fd5b613abc8d838e016138ba565b909650945060808c0135915080821115613ad557600080fd5b50613ae28c828d016138ba565b915080935050809150509295985092959850929598565b600060208284031215613b0b57600080fd5b8135610486816139e5565b60008060408385031215613b2957600080fd5b50508035926020909101359150565b634e487b7160e01b600052602160045260246000fd5b600281106105aa576105aa613b38565b600081518084526020808501945080840160005b83811015613ba7578151805160ff16885283810151848901526040908101519088015260609096019590820190600101613b72565b509495945050505050565b604080825283519082018190526000906020906060840190828701845b82811015613bf4578151613be281613b4e565b84529284019290840190600101613bcf565b50505083810382850152613c088186613b5e565b9695505050505050565b600080600060608486031215613c2757600080fd5b83359250602084013591506040840135613c40816139e5565b809150509250925092565b600060208284031215613c5d57600080fd5b5035919050565b600080600080600060608688031215613c7c57600080fd5b85356001600160401b0380821115613c9357600080fd5b9087019060c0828a03121561398c57600080fd5b600080600060408486031215613cbc57600080fd5b8335925060208401356001600160401b03811115613cd957600080fd5b613ce5868287016138ba565b9497909650939450505050565b6020815260006104866020830184613b5e565b600080600080600060608688031215613d1d57600080fd5b8535945060208601356001600160401b03808211156139a257600080fd5b60008060408385031215613d4e57600080fd5b8235613d59816139e5565b91506020830135613a1f816139e5565b60008060008060008060008060008060c08b8d031215613d8857600080fd5b8a35995060208b0135985060408b01356001600160401b0380821115613dad57600080fd5b613db98e838f016138ba565b909a50985060608d0135915080821115613dd257600080fd5b613dde8e838f016138ba565b909850965060808d0135915080821115613df757600080fd5b613e038e838f016138ba565b909650945060a08d0135915080821115613e1c57600080fd5b50613e298d828e016138ba565b915080935050809150509295989b9194979a5092959850565b60a0810160048710613e5657613e56613b38565b95815260208101949094526040840192909252606083015260809091015290565b60208082526027908201527f476f7665726e616e636541646d696e3a2073656e646572206973206e6f74206760408201526637bb32b93737b960c91b606082015260800190565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b0381118282101715613ef657613ef6613ebe565b60405290565b60405160c081016001600160401b0381118282101715613ef657613ef6613ebe565b604051601f8201601f191681016001600160401b0381118282101715613f4657613f46613ebe565b604052919050565b60006001600160401b03821115613f6757613f67613ebe565b5060051b60200190565b6000613f84613f7f84613f4e565b613f1e565b8381529050602080820190600585901b840186811115613fa357600080fd5b845b818110156140365780356001600160401b0380821115613fc55760008081fd5b8188019150601f8a81840112613fdb5760008081fd5b823582811115613fed57613fed613ebe565b613ffe818301601f19168801613f1e565b92508083528b8782860101111561401757600091508182fd5b8087850188850137600090830187015250855250928201928201613fa5565b505050509392505050565b6000610486368484613f71565b60208082526027908201527f476f7665726e616e636541646d696e3a206f6e6c7920616c6c6f7765642073656040820152661b198b58d85b1b60ca1b606082015260800190565b60208082526024908201527f476f7665726e616e636541646d696e3a2073657420746f206e6f6e2d636f6e746040820152631c9858dd60e21b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b80820180821115610489576104896140d9565b634e487b7160e01b600052603260045260246000fd5b60006001820161412a5761412a6140d9565b5060010190565b60006020828403121561414357600080fd5b8151610486816139e5565b83815260406020808301829052908201839052600090849060608401835b8681101561419a57833561417f816139e5565b6001600160a01b03168252928201929082019060010161416c565b50979650505050505050565b60005b838110156141c15781810151838201526020016141a9565b50506000910152565b600082516141dc8184602087016141a6565b9190910192915050565b600081518084526141fe8160208601602086016141a6565b601f01601f19169290920160200192915050565b60208152600061048660208301846141e6565b60006020828403121561423757600080fd5b5051919050565b600082601f83011261424f57600080fd5b8135602061425f613f7f83613f4e565b82815260059290921b8401810191818101908684111561427e57600080fd5b8286015b848110156142a2578035614295816139e5565b8352918301918301614282565b509695505050505050565b600082601f8301126142be57600080fd5b813560206142ce613f7f83613f4e565b82815260059290921b840181019181810190868411156142ed57600080fd5b8286015b848110156142a257803583529183019183016142f1565b600082601f83011261431957600080fd5b61048683833560208501613f71565b600060e0823603121561433a57600080fd5b614342613ed4565b82358152602083013560208201526040830135604082015260608301356001600160401b038082111561437457600080fd5b6143803683870161423e565b6060840152608085013591508082111561439957600080fd5b6143a5368387016142ad565b608084015260a08501359150808211156143be57600080fd5b6143ca36838701614308565b60a084015260c08501359150808211156143e357600080fd5b506143f0368286016142ad565b60c08301525092915050565b600081518084526020808501945080840160005b83811015613ba757815187529582019590820190600101614410565b600081518084526020808501808196508360051b8101915082860160005b858110156144745782840389526144628483516141e6565b9885019893509084019060010161444a565b5091979650505050505050565b600060e08301825184526020808401518186015260408401516040860152606084015160e06060870152828151808552610100880191508383019450600092505b808310156144eb5784516001600160a01b031682529383019360019290920191908301906144c2565b5060808601519350868103608088015261450581856143fc565b935050505060a083015184820360a0860152614521828261442c565b91505060c083015184820360c086015261453b82826143fc565b95945050505050565b6080815260006145576080830187614481565b60208681850152838203604085015260c08201865183528187015182840152604087015160c0604085015281815180845260e0860191508483019350600092505b808310156145c15783516145ab81613b4e565b8252928401926001929092019190840190614598565b506060890151935084810360608601526145db81856143fc565b9350505050608086015182820360808401526145f7828261442c565b91505060a086015182820360a084015261461182826143fc565b935050505061453b60608301846001600160a01b03169052565b6020808252602f908201527f476f7665726e616e636541646d696e3a206361737420766f746520666f72206960408201526e1b9d985b1a59081c1c9bdc1bdcd85b608a1b606082015260800190565b600281106105aa57600080fd5b600082601f83011261469857600080fd5b813560206146a8613f7f83613f4e565b82815260059290921b840181019181810190868411156146c757600080fd5b8286015b848110156142a25780356146de8161467a565b83529183019183016146cb565b600060c082360312156146fd57600080fd5b614705613efc565b823581526020830135602082015260408301356001600160401b038082111561472d57600080fd5b61473936838701614687565b6040840152606085013591508082111561475257600080fd5b61475e368387016142ad565b6060840152608085013591508082111561477757600080fd5b61478336838701614308565b608084015260a085013591508082111561479c57600080fd5b506147a9368286016142ad565b60a08301525092915050565b6000606082840312156147c757600080fd5b604051606081018181106001600160401b03821117156147e9576147e9613ebe565b604052823560ff811681146147fd57600080fd5b8152602083810135908201526040928301359281019290925250919050565b60408152600061482f6040830185614481565b905060018060a01b03831660208301529392505050565b60208082526026908201527f436f7265476f7665726e616e63653a20696e76616c69642070726f706f73616c604082015265206e6f6e636560d01b606082015260800190565b83815260208101839052606081016148a383613b4e565b826040830152949350505050565b81810381811115610489576104896140d9565b6000602082840312156148d657600080fd5b81356104868161467a565b73024b9b7b630ba32b223b7bb32b93730b731b29d160651b8152600082516149108160148501602087016141a6565b6d08185b1c9958591e481d9bdd195960921b6014939091019283015250602201919050565b6f021b7b932a3b7bb32b93730b731b29d160851b8152600082516149608160108501602087016141a6565b6d08185b1c9958591e481d9bdd195960921b6010939091019283015250601e01919050565b6040810161499284613b4e565b9281526020015290565b8082028115828204841417610489576104896140d9565b6000816149c2576149c26140d9565b506000190190565b604080825283519082018190526000906020906060840190828701845b82811015614a055781511515845292840192908401906001016149e7565b50505083810382850152613c08818661442c56fef8704f8860d9e985bf6c52ec4738bd10fe31487599b36c0944f746ea09dc256ba2646970667358221220b8c44859a99fef98140e7036521676f05098a664fa30b41b44982148a6a7162764736f6c63430008110033", + "numDeployments": 3, + "solcInputHash": "9c14b324033beb5ee990c4b68d9e780e", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_roninTrustedOrganizationContract\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bridgeContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_proposalExpiryDuration\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"BridgeContractUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_period\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"_operators\",\"type\":\"address[]\"}],\"name\":\"BridgeOperatorsApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"round\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"targets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasAmounts\",\"type\":\"uint256[]\"}],\"indexed\":false,\"internalType\":\"struct Proposal.ProposalDetail\",\"name\":\"proposal\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"globalProposalHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"enum GlobalProposal.TargetOption[]\",\"name\":\"targetOptions\",\"type\":\"uint8[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasAmounts\",\"type\":\"uint256[]\"}],\"indexed\":false,\"internalType\":\"struct GlobalProposal.GlobalProposalDetail\",\"name\":\"globalProposal\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"}],\"name\":\"GlobalProposalCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"}],\"name\":\"ProposalApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"round\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"targets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasAmounts\",\"type\":\"uint256[]\"}],\"indexed\":false,\"internalType\":\"struct Proposal.ProposalDetail\",\"name\":\"proposal\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"}],\"name\":\"ProposalCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool[]\",\"name\":\"successCalls\",\"type\":\"bool[]\"},{\"indexed\":false,\"internalType\":\"bytes[]\",\"name\":\"returnDatas\",\"type\":\"bytes[]\"}],\"name\":\"ProposalExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"}],\"name\":\"ProposalExpired\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"}],\"name\":\"ProposalRejected\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"proposalHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enum Ballot.VoteType\",\"name\":\"support\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"name\":\"ProposalVoted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"RoninTrustedOrganizationContractUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridgeContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_period\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_voter\",\"type\":\"address\"}],\"name\":\"bridgeOperatorsVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"enum GlobalProposal.TargetOption[]\",\"name\":\"targetOptions\",\"type\":\"uint8[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasAmounts\",\"type\":\"uint256[]\"}],\"internalType\":\"struct GlobalProposal.GlobalProposalDetail\",\"name\":\"_globalProposal\",\"type\":\"tuple\"},{\"internalType\":\"enum Ballot.VoteType[]\",\"name\":\"_supports\",\"type\":\"uint8[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct SignatureConsumer.Signature[]\",\"name\":\"_signatures\",\"type\":\"tuple[]\"}],\"name\":\"castGlobalProposalBySignatures\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"targets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasAmounts\",\"type\":\"uint256[]\"}],\"internalType\":\"struct Proposal.ProposalDetail\",\"name\":\"_proposal\",\"type\":\"tuple\"},{\"internalType\":\"enum Ballot.VoteType[]\",\"name\":\"_supports\",\"type\":\"uint8[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct SignatureConsumer.Signature[]\",\"name\":\"_signatures\",\"type\":\"tuple[]\"}],\"name\":\"castProposalBySignatures\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"round\",\"type\":\"uint256\"}],\"name\":\"deleteExpired\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_period\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"_voters\",\"type\":\"address[]\"}],\"name\":\"getBridgeOperatorVotingSignatures\",\"outputs\":[{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct SignatureConsumer.Signature[]\",\"name\":\"_signatures\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getProposalExpiryDuration\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_round\",\"type\":\"uint256\"}],\"name\":\"getProposalSignatures\",\"outputs\":[{\"internalType\":\"enum Ballot.VoteType[]\",\"name\":\"_supports\",\"type\":\"uint8[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct SignatureConsumer.Signature[]\",\"name\":\"_signatures\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridgeVoter\",\"type\":\"address\"}],\"name\":\"lastVotedBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_round\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_voter\",\"type\":\"address\"}],\"name\":\"proposalVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"_targets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_gasAmounts\",\"type\":\"uint256[]\"}],\"name\":\"propose\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"enum GlobalProposal.TargetOption[]\",\"name\":\"_targetOptions\",\"type\":\"uint8[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_gasAmounts\",\"type\":\"uint256[]\"}],\"name\":\"proposeGlobal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"enum GlobalProposal.TargetOption[]\",\"name\":\"targetOptions\",\"type\":\"uint8[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasAmounts\",\"type\":\"uint256[]\"}],\"internalType\":\"struct GlobalProposal.GlobalProposalDetail\",\"name\":\"_globalProposal\",\"type\":\"tuple\"},{\"internalType\":\"enum Ballot.VoteType[]\",\"name\":\"_supports\",\"type\":\"uint8[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct SignatureConsumer.Signature[]\",\"name\":\"_signatures\",\"type\":\"tuple[]\"}],\"name\":\"proposeGlobalProposalStructAndCastVotes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiryTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"targets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasAmounts\",\"type\":\"uint256[]\"}],\"internalType\":\"struct Proposal.ProposalDetail\",\"name\":\"_proposal\",\"type\":\"tuple\"},{\"internalType\":\"enum Ballot.VoteType[]\",\"name\":\"_supports\",\"type\":\"uint8[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct SignatureConsumer.Signature[]\",\"name\":\"_signatures\",\"type\":\"tuple[]\"}],\"name\":\"proposeProposalStructAndCastVotes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"roninTrustedOrganizationContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"round\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"setBridgeContract\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_expiryDuration\",\"type\":\"uint256\"}],\"name\":\"setProposalExpiryDuration\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"setRoninTrustedOrganizationContract\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"vote\",\"outputs\":[{\"internalType\":\"enum VoteStatusConsumer.VoteStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"againstVoteWeight\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"forVoteWeight\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiryTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_period\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"_operators\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct SignatureConsumer.Signature[]\",\"name\":\"_signatures\",\"type\":\"tuple[]\"}],\"name\":\"voteBridgeOperatorsBySignatures\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"BridgeOperatorsApproved(uint256,address[])\":{\"details\":\"Emitted when the bridge operators are approved.\"}},\"kind\":\"dev\",\"methods\":{\"bridgeContract()\":{\"details\":\"Returns the bridge contract.\"},\"bridgeOperatorsVoted(uint256,address)\":{\"details\":\"Returns whether the voter `_voter` casted vote for bridge operators at a specific period.\"},\"castGlobalProposalBySignatures((uint256,uint256,uint8[],uint256[],bytes[],uint256[]),uint8[],(uint8,bytes32,bytes32)[])\":{\"details\":\"See `GovernanceProposal-_castGlobalProposalBySignatures`.\"},\"castProposalBySignatures((uint256,uint256,uint256,address[],uint256[],bytes[],uint256[]),uint8[],(uint8,bytes32,bytes32)[])\":{\"details\":\"See `GovernanceProposal-_castProposalBySignatures`.\"},\"changeProxyAdmin(address,address)\":{\"details\":\"Changes the admin of `_proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `_proxy`.\"},\"deleteExpired(uint256,uint256)\":{\"details\":\"See `CoreGovernance-_deleteExpiredProposal`\"},\"getBridgeOperatorVotingSignatures(uint256,address[])\":{\"details\":\"Returns the voted signatures for bridge operators at a specific period. Note: Does not verify whether the voter casted vote for the proposal and the returned signature can be empty. Please consider filtering for empty signatures after calling this function.\"},\"getProposalExpiryDuration()\":{\"details\":\"Returns the proposal expiry duration.\"},\"getProposalSignatures(uint256,uint256)\":{\"details\":\"Returns the voted signatures for the proposals.\"},\"getProxyAdmin(address)\":{\"details\":\"Returns the current admin of `_proxy`. Requirements: - This contract must be the admin of `_proxy`.\"},\"getProxyImplementation(address)\":{\"details\":\"Returns the current implementation of `_proxy`. Requirements: - This contract must be the admin of `_proxy`.\"},\"lastVotedBlock(address)\":{\"details\":\"Returns the last voted block of the bridge voter.\"},\"proposalVoted(uint256,uint256,address)\":{\"details\":\"Returns whether the voter `_voter` casted vote for the proposal.\"},\"propose(uint256,uint256,address[],uint256[],bytes[],uint256[])\":{\"details\":\"See `CoreGovernance-_proposeProposal`. Requirements: - The method caller is governor.\"},\"proposeGlobal(uint256,uint8[],uint256[],bytes[],uint256[])\":{\"details\":\"See `CoreGovernance-_proposeGlobal`. Requirements: - The method caller is governor.\"},\"proposeGlobalProposalStructAndCastVotes((uint256,uint256,uint8[],uint256[],bytes[],uint256[]),uint8[],(uint8,bytes32,bytes32)[])\":{\"details\":\"See `GovernanceProposal-_proposeGlobalProposalStructAndCastVotes`. Requirements: - The method caller is governor.\"},\"proposeProposalStructAndCastVotes((uint256,uint256,uint256,address[],uint256[],bytes[],uint256[]),uint8[],(uint8,bytes32,bytes32)[])\":{\"details\":\"See `GovernanceProposal-_proposeProposalStructAndCastVotes`. Requirements: - The method caller is governor.\"},\"roninTrustedOrganizationContract()\":{\"details\":\"Returns the ronin trusted organization contract.\"},\"setBridgeContract(address)\":{\"details\":\"Sets the bridge contract. Requirements: - The method caller is admin. - The new address is a contract. Emits the event `BridgeContractUpdated`.\"},\"setProposalExpiryDuration(uint256)\":{\"details\":\"Sets the expiry duration for a new proposal. Requirements: - Only allowing self-call to this method, since this contract does not have admin.\"},\"setRoninTrustedOrganizationContract(address)\":{\"details\":\"Sets the ronin trusted organization contract. Requirements: - The method caller is admin. - The new address is a contract. Emits the event `RoninTrustedOrganizationContractUpdated`.\"},\"voteBridgeOperatorsBySignatures(uint256,address[],(uint8,bytes32,bytes32)[])\":{\"details\":\"See `BOsGovernanceProposal-_castVotesBySignatures`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"round(uint256)\":{\"notice\":\"chain id = 0 for global proposal\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ronin/RoninGovernanceAdmin.sol\":\"RoninGovernanceAdmin\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xdb7f5c28fc61cda0bd8ab60ce288e206b791643bcd3ba464a70cbec18895a2f5\",\"license\":\"MIT\"},\"contracts/extensions/GovernanceAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"../extensions/sequential-governance/CoreGovernance.sol\\\";\\nimport \\\"../extensions/collections/HasRoninTrustedOrganizationContract.sol\\\";\\nimport \\\"../extensions/collections/HasBridgeContract.sol\\\";\\nimport \\\"../interfaces/IRoninTrustedOrganization.sol\\\";\\n\\nabstract contract GovernanceAdmin is CoreGovernance, HasRoninTrustedOrganizationContract, HasBridgeContract {\\n /// @dev Domain separator\\n bytes32 public constant DOMAIN_SEPARATOR = 0xf8704f8860d9e985bf6c52ec4738bd10fe31487599b36c0944f746ea09dc256b;\\n\\n modifier onlySelfCall() {\\n require(msg.sender == address(this), \\\"GovernanceAdmin: only allowed self-call\\\");\\n _;\\n }\\n\\n constructor(\\n address _roninTrustedOrganizationContract,\\n address _bridgeContract,\\n uint256 _proposalExpiryDuration\\n ) CoreGovernance(_proposalExpiryDuration) {\\n require(\\n keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,bytes32 salt)\\\"),\\n keccak256(\\\"GovernanceAdmin\\\"), // name hash\\n keccak256(\\\"1\\\"), // version hash\\n keccak256(abi.encode(\\\"RONIN_GOVERNANCE_ADMIN\\\", 2020)) // salt\\n )\\n ) == DOMAIN_SEPARATOR,\\n \\\"GovernanceAdmin: invalid domain\\\"\\n );\\n _setRoninTrustedOrganizationContract(_roninTrustedOrganizationContract);\\n _setBridgeContract(_bridgeContract);\\n }\\n\\n /**\\n * @inheritdoc IHasRoninTrustedOrganizationContract\\n */\\n function setRoninTrustedOrganizationContract(address _addr) external override onlySelfCall {\\n require(_addr.code.length > 0, \\\"GovernanceAdmin: set to non-contract\\\");\\n _setRoninTrustedOrganizationContract(_addr);\\n }\\n\\n /**\\n * @inheritdoc IHasBridgeContract\\n */\\n function setBridgeContract(address _addr) external override onlySelfCall {\\n require(_addr.code.length > 0, \\\"GovernanceAdmin: set to non-contract\\\");\\n _setBridgeContract(_addr);\\n }\\n\\n /**\\n * @dev Sets the expiry duration for a new proposal.\\n *\\n * Requirements:\\n * - Only allowing self-call to this method, since this contract does not have admin.\\n *\\n */\\n function setProposalExpiryDuration(uint256 _expiryDuration) external onlySelfCall {\\n _setProposalExpiryDuration(_expiryDuration);\\n }\\n\\n /**\\n * @dev Returns the current implementation of `_proxy`.\\n *\\n * Requirements:\\n * - This contract must be the admin of `_proxy`.\\n *\\n */\\n function getProxyImplementation(address _proxy) external view returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"implementation()\\\")) == 0x5c60da1b\\n (bool _success, bytes memory _returndata) = _proxy.staticcall(hex\\\"5c60da1b\\\");\\n require(_success, \\\"GovernanceAdmin: proxy call `implementation()` failed\\\");\\n return abi.decode(_returndata, (address));\\n }\\n\\n /**\\n * @dev Returns the proposal expiry duration.\\n */\\n function getProposalExpiryDuration() external view returns (uint256) {\\n return super._getProposalExpiryDuration();\\n }\\n\\n /**\\n * @dev Returns the current admin of `_proxy`.\\n *\\n * Requirements:\\n * - This contract must be the admin of `_proxy`.\\n *\\n */\\n function getProxyAdmin(address _proxy) external view returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"admin()\\\")) == 0xf851a440\\n (bool _success, bytes memory _returndata) = _proxy.staticcall(hex\\\"f851a440\\\");\\n require(_success, \\\"GovernanceAdmin: proxy call `admin()` failed\\\");\\n return abi.decode(_returndata, (address));\\n }\\n\\n /**\\n * @dev Changes the admin of `_proxy` to `newAdmin`.\\n *\\n * Requirements:\\n * - This contract must be the current admin of `_proxy`.\\n *\\n */\\n function changeProxyAdmin(address _proxy, address _newAdmin) external onlySelfCall {\\n // bytes4(keccak256(\\\"changeAdmin(address)\\\"))\\n (bool _success, ) = _proxy.call(abi.encodeWithSelector(0x8f283970, _newAdmin));\\n require(_success, \\\"GovernanceAdmin: proxy call `changeAdmin(address)` failed\\\");\\n }\\n\\n /**\\n * @dev Override `CoreGovernance-_getMinimumVoteWeight`.\\n */\\n function _getMinimumVoteWeight() internal view virtual override returns (uint256) {\\n (bool _success, bytes memory _returndata) = roninTrustedOrganizationContract().staticcall(\\n abi.encodeWithSelector(\\n // TransparentUpgradeableProxyV2.functionDelegateCall.selector,\\n 0x4bb5274a,\\n abi.encodeWithSelector(IQuorum.minimumVoteWeight.selector)\\n )\\n );\\n require(_success, \\\"GovernanceAdmin: proxy call `minimumVoteWeight()` failed\\\");\\n return abi.decode(_returndata, (uint256));\\n }\\n\\n /**\\n * @dev Override `CoreGovernance-_getTotalWeights`.\\n */\\n function _getTotalWeights() internal view virtual override returns (uint256) {\\n (bool _success, bytes memory _returndata) = roninTrustedOrganizationContract().staticcall(\\n abi.encodeWithSelector(\\n // TransparentUpgradeableProxyV2.functionDelegateCall.selector,\\n 0x4bb5274a,\\n abi.encodeWithSelector(IRoninTrustedOrganization.totalWeights.selector)\\n )\\n );\\n require(_success, \\\"GovernanceAdmin: proxy call `totalWeights()` failed\\\");\\n return abi.decode(_returndata, (uint256));\\n }\\n}\\n\",\"keccak256\":\"0x07e179dc68e1d5a860b2b0c9f50730307ec681e3a32c1e41bca5cdcda5e3da51\",\"license\":\"MIT\"},\"contracts/extensions/collections/HasBridgeContract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./HasProxyAdmin.sol\\\";\\nimport \\\"../../interfaces/collections/IHasBridgeContract.sol\\\";\\nimport \\\"../../interfaces/IBridge.sol\\\";\\n\\ncontract HasBridgeContract is IHasBridgeContract, HasProxyAdmin {\\n IBridge internal _bridgeContract;\\n\\n modifier onlyBridgeContract() {\\n require(bridgeContract() == msg.sender, \\\"HasBridgeContract: method caller must be bridge contract\\\");\\n _;\\n }\\n\\n /**\\n * @inheritdoc IHasBridgeContract\\n */\\n function bridgeContract() public view override returns (address) {\\n return address(_bridgeContract);\\n }\\n\\n /**\\n * @inheritdoc IHasBridgeContract\\n */\\n function setBridgeContract(address _addr) external virtual override onlyAdmin {\\n require(_addr.code.length > 0, \\\"HasBridgeContract: set to non-contract\\\");\\n _setBridgeContract(_addr);\\n }\\n\\n /**\\n * @dev Sets the bridge contract.\\n *\\n * Emits the event `BridgeContractUpdated`.\\n *\\n */\\n function _setBridgeContract(address _addr) internal {\\n _bridgeContract = IBridge(_addr);\\n emit BridgeContractUpdated(_addr);\\n }\\n}\\n\",\"keccak256\":\"0xf4dfa576336d50ab380c3310735575f8729cff0089813abb1a8506ad2cca0f00\",\"license\":\"MIT\"},\"contracts/extensions/collections/HasProxyAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/StorageSlot.sol\\\";\\n\\nabstract contract HasProxyAdmin {\\n // bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n modifier onlyAdmin() {\\n require(msg.sender == _getAdmin(), \\\"HasProxyAdmin: unauthorized sender\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns proxy admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n}\\n\",\"keccak256\":\"0x0c2fcf25290180e8cd733691b113464cdde671dc019e6c343e9eb3e16c6ca24a\",\"license\":\"MIT\"},\"contracts/extensions/collections/HasRoninTrustedOrganizationContract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./HasProxyAdmin.sol\\\";\\nimport \\\"../../interfaces/collections/IHasRoninTrustedOrganizationContract.sol\\\";\\nimport \\\"../../interfaces/IRoninTrustedOrganization.sol\\\";\\n\\ncontract HasRoninTrustedOrganizationContract is IHasRoninTrustedOrganizationContract, HasProxyAdmin {\\n IRoninTrustedOrganization internal _roninTrustedOrganizationContract;\\n\\n modifier onlyRoninTrustedOrganizationContract() {\\n require(\\n roninTrustedOrganizationContract() == msg.sender,\\n \\\"HasRoninTrustedOrganizationContract: method caller must be ronin trusted organization contract\\\"\\n );\\n _;\\n }\\n\\n /**\\n * @inheritdoc IHasRoninTrustedOrganizationContract\\n */\\n function roninTrustedOrganizationContract() public view override returns (address) {\\n return address(_roninTrustedOrganizationContract);\\n }\\n\\n /**\\n * @inheritdoc IHasRoninTrustedOrganizationContract\\n */\\n function setRoninTrustedOrganizationContract(address _addr) external virtual override onlyAdmin {\\n require(_addr.code.length > 0, \\\"HasRoninTrustedOrganizationContract: set to non-contract\\\");\\n _setRoninTrustedOrganizationContract(_addr);\\n }\\n\\n /**\\n * @dev Sets the ronin trusted organization contract.\\n *\\n * Emits the event `RoninTrustedOrganizationContractUpdated`.\\n *\\n */\\n function _setRoninTrustedOrganizationContract(address _addr) internal {\\n _roninTrustedOrganizationContract = IRoninTrustedOrganization(_addr);\\n emit RoninTrustedOrganizationContractUpdated(_addr);\\n }\\n}\\n\",\"keccak256\":\"0xbdfbd30aa984f10f191b21e4b790ff1872445c7387cf359aadd863aac6635507\",\"license\":\"MIT\"},\"contracts/extensions/isolated-governance/IsolatedGovernance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport \\\"../../interfaces/consumers/VoteStatusConsumer.sol\\\";\\n\\nabstract contract IsolatedGovernance is VoteStatusConsumer {\\n struct IsolatedVote {\\n VoteStatus status;\\n bytes32 finalHash;\\n /// @dev Mapping from voter => receipt hash\\n mapping(address => bytes32) voteHashOf;\\n /// @dev Mapping from receipt hash => vote weight\\n mapping(bytes32 => uint256) weight;\\n }\\n\\n /**\\n * @dev Casts vote for the receipt with the receipt hash `_hash`.\\n *\\n * Requirements:\\n * - The vote is not finalized.\\n * - The voter has not voted for the round.\\n *\\n */\\n function _castVote(\\n IsolatedVote storage _proposal,\\n address _voter,\\n uint256 _voterWeight,\\n uint256 _minimumVoteWeight,\\n bytes32 _hash\\n ) internal virtual returns (VoteStatus _status) {\\n if (_voted(_proposal, _voter)) {\\n revert(\\n string(abi.encodePacked(\\\"IsolatedGovernance: \\\", Strings.toHexString(uint160(_voter), 20), \\\" already voted\\\"))\\n );\\n }\\n\\n // Record for voter\\n _proposal.voteHashOf[_voter] = _hash;\\n // Increase vote weight\\n uint256 _weight = _proposal.weight[_hash] += _voterWeight;\\n\\n if (_weight >= _minimumVoteWeight && _proposal.status == VoteStatus.Pending) {\\n _proposal.status = VoteStatus.Approved;\\n _proposal.finalHash = _hash;\\n }\\n\\n _status = _proposal.status;\\n }\\n\\n /**\\n * @dev Returns whether the voter casted for the proposal.\\n */\\n function _voted(IsolatedVote storage _proposal, address _voter) internal view virtual returns (bool) {\\n return _proposal.voteHashOf[_voter] != bytes32(0);\\n }\\n}\\n\",\"keccak256\":\"0x0c84a1e18e5472ec179c0ccba6de642ad53e26a908f66f7fedc1f85499e2513c\",\"license\":\"MIT\"},\"contracts/extensions/isolated-governance/bridge-operator-governance/BOsGovernanceProposal.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../../extensions/isolated-governance/IsolatedGovernance.sol\\\";\\nimport \\\"../../../interfaces/consumers/SignatureConsumer.sol\\\";\\nimport \\\"../../../libraries/BridgeOperatorsBallot.sol\\\";\\nimport \\\"../../../interfaces/IRoninGovernanceAdmin.sol\\\";\\n\\nabstract contract BOsGovernanceProposal is SignatureConsumer, IsolatedGovernance, IRoninGovernanceAdmin {\\n /// @dev The last period that the brige operators synced.\\n uint256 internal _lastSyncedPeriod;\\n /// @dev Mapping from period index => bridge operators vote\\n mapping(uint256 => IsolatedVote) internal _vote;\\n\\n /// @dev Mapping from bridge voter address => last block that the address voted\\n mapping(address => uint256) internal _lastVotedBlock;\\n /// @dev Mapping from period => voter => signatures\\n mapping(uint256 => mapping(address => Signature)) internal _votingSig;\\n\\n /**\\n * @inheritdoc IRoninGovernanceAdmin\\n */\\n function lastVotedBlock(address _bridgeVoter) external view returns (uint256) {\\n return _lastVotedBlock[_bridgeVoter];\\n }\\n\\n /**\\n * @dev Votes for a set of bridge operators by signatures.\\n *\\n * Requirements:\\n * - The period of voting is larger than the last synced period.\\n * - The arrays are not empty.\\n * - The signature signers are in order.\\n *\\n */\\n function _castVotesBySignatures(\\n address[] calldata _operators,\\n Signature[] calldata _signatures,\\n uint256 _period,\\n uint256 _minimumVoteWeight,\\n bytes32 _domainSeperator\\n ) internal {\\n require(_period >= _lastSyncedPeriod, \\\"BOsGovernanceProposal: query for outdated period\\\");\\n require(_operators.length > 0 && _signatures.length > 0, \\\"BOsGovernanceProposal: invalid array length\\\");\\n\\n Signature memory _sig;\\n address _signer;\\n address _lastSigner;\\n bytes32 _hash = BridgeOperatorsBallot.hash(_period, _operators);\\n bytes32 _digest = ECDSA.toTypedDataHash(_domainSeperator, _hash);\\n IsolatedVote storage _v = _vote[_period];\\n bool _hasValidVotes;\\n\\n for (uint256 _i = 0; _i < _signatures.length; _i++) {\\n _sig = _signatures[_i];\\n _signer = ECDSA.recover(_digest, _sig.v, _sig.r, _sig.s);\\n require(_lastSigner < _signer, \\\"BOsGovernanceProposal: invalid order\\\");\\n _lastSigner = _signer;\\n\\n uint256 _weight = _getBridgeVoterWeight(_signer);\\n if (_weight > 0) {\\n _hasValidVotes = true;\\n _lastVotedBlock[_signer] = block.number;\\n _votingSig[_period][_signer] = _sig;\\n if (_castVote(_v, _signer, _weight, _minimumVoteWeight, _hash) == VoteStatus.Approved) {\\n return;\\n }\\n }\\n }\\n\\n require(_hasValidVotes, \\\"BOsGovernanceProposal: invalid signatures\\\");\\n }\\n\\n /**\\n * @dev Returns the weight of a bridge voter.\\n */\\n function _getBridgeVoterWeight(address _bridgeVoter) internal view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xdaeae7aa91963ce5160cce59482eb1366a6d85692deaf7504a4b18735ff2cfd2\",\"license\":\"MIT\"},\"contracts/extensions/sequential-governance/CoreGovernance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport \\\"../../libraries/Proposal.sol\\\";\\nimport \\\"../../libraries/GlobalProposal.sol\\\";\\nimport \\\"../../libraries/Ballot.sol\\\";\\nimport \\\"../../interfaces/consumers/ChainTypeConsumer.sol\\\";\\nimport \\\"../../interfaces/consumers/SignatureConsumer.sol\\\";\\nimport \\\"../../interfaces/consumers/VoteStatusConsumer.sol\\\";\\n\\nabstract contract CoreGovernance is SignatureConsumer, VoteStatusConsumer, ChainTypeConsumer {\\n using Proposal for Proposal.ProposalDetail;\\n using GlobalProposal for GlobalProposal.GlobalProposalDetail;\\n\\n struct ProposalVote {\\n VoteStatus status;\\n bytes32 hash;\\n uint256 againstVoteWeight; // Total weight of against votes\\n uint256 forVoteWeight; // Total weight of for votes\\n address[] forVoteds; // Array of addresses voting for\\n address[] againstVoteds; // Array of addresses voting against\\n uint256 expiryTimestamp;\\n mapping(address => Signature) sig;\\n }\\n\\n /// @dev Emitted when a proposal is created\\n event ProposalCreated(\\n uint256 indexed chainId,\\n uint256 indexed round,\\n bytes32 indexed proposalHash,\\n Proposal.ProposalDetail proposal,\\n address creator\\n );\\n /// @dev Emitted when a proposal is created\\n event GlobalProposalCreated(\\n uint256 indexed round,\\n bytes32 indexed proposalHash,\\n Proposal.ProposalDetail proposal,\\n bytes32 globalProposalHash,\\n GlobalProposal.GlobalProposalDetail globalProposal,\\n address creator\\n );\\n /// @dev Emitted when the proposal is voted\\n event ProposalVoted(bytes32 indexed proposalHash, address indexed voter, Ballot.VoteType support, uint256 weight);\\n /// @dev Emitted when the proposal is approved\\n event ProposalApproved(bytes32 indexed proposalHash);\\n /// @dev Emitted when the vote is reject\\n event ProposalRejected(bytes32 indexed proposalHash);\\n /// @dev Emitted when the vote is expired\\n event ProposalExpired(bytes32 indexed proposalHash);\\n /// @dev Emitted when the proposal is executed\\n event ProposalExecuted(bytes32 indexed proposalHash, bool[] successCalls, bytes[] returnDatas);\\n\\n /// @dev Mapping from chain id => vote round\\n /// @notice chain id = 0 for global proposal\\n mapping(uint256 => uint256) public round;\\n /// @dev Mapping from chain id => vote round => proposal vote\\n mapping(uint256 => mapping(uint256 => ProposalVote)) public vote;\\n\\n uint256 private _proposalExpiryDuration;\\n\\n constructor(uint256 _expiryDuration) {\\n _setProposalExpiryDuration(_expiryDuration);\\n }\\n\\n /**\\n * @dev Creates new round voting for the proposal `_proposalHash` of chain `_chainId`.\\n */\\n function _createVotingRound(\\n uint256 _chainId,\\n bytes32 _proposalHash,\\n uint256 _expiryTimestamp\\n ) internal returns (uint256 _round) {\\n _round = round[_chainId];\\n\\n // Skip checking for the first ever round\\n if (_round == 0) {\\n _round = round[_chainId] = 1;\\n } else {\\n ProposalVote storage _latestProposalVote = vote[_chainId][_round];\\n bool _isExpired = _tryDeleteExpiredVotingRound(_latestProposalVote);\\n // Skip increase round number if the latest round is expired, allow the vote to be overridden\\n if (!_isExpired) {\\n require(_latestProposalVote.status != VoteStatus.Pending, \\\"CoreGovernance: current proposal is not completed\\\");\\n _round = ++round[_chainId];\\n }\\n }\\n\\n vote[_chainId][_round].hash = _proposalHash;\\n vote[_chainId][_round].expiryTimestamp = _expiryTimestamp;\\n }\\n\\n /**\\n * @dev Proposes for a new proposal.\\n *\\n * Requirements:\\n * - The chain id is not equal to 0.\\n *\\n * Emits the `ProposalCreated` event.\\n *\\n */\\n function _proposeProposal(\\n uint256 _chainId,\\n uint256 _expiryTimestamp,\\n address[] memory _targets,\\n uint256[] memory _values,\\n bytes[] memory _calldatas,\\n uint256[] memory _gasAmounts,\\n address _creator\\n ) internal virtual returns (uint256 _round) {\\n require(_chainId != 0, \\\"CoreGovernance: invalid chain id\\\");\\n\\n Proposal.ProposalDetail memory _proposal = Proposal.ProposalDetail(\\n round[_chainId] + 1,\\n _chainId,\\n _expiryTimestamp,\\n _targets,\\n _values,\\n _calldatas,\\n _gasAmounts\\n );\\n _proposal.validate(_proposalExpiryDuration);\\n\\n bytes32 _proposalHash = _proposal.hash();\\n _round = _createVotingRound(_chainId, _proposalHash, _expiryTimestamp);\\n emit ProposalCreated(_chainId, _round, _proposalHash, _proposal, _creator);\\n }\\n\\n /**\\n * @dev Proposes proposal struct.\\n *\\n * Requirements:\\n * - The chain id is not equal to 0.\\n * - The proposal nonce is equal to the new round.\\n *\\n * Emits the `ProposalCreated` event.\\n *\\n */\\n function _proposeProposalStruct(Proposal.ProposalDetail memory _proposal, address _creator)\\n internal\\n virtual\\n returns (uint256 _round)\\n {\\n uint256 _chainId = _proposal.chainId;\\n require(_chainId != 0, \\\"CoreGovernance: invalid chain id\\\");\\n _proposal.validate(_proposalExpiryDuration);\\n\\n bytes32 _proposalHash = _proposal.hash();\\n _round = _createVotingRound(_chainId, _proposalHash, _proposal.expiryTimestamp);\\n require(_round == _proposal.nonce, \\\"CoreGovernance: invalid proposal nonce\\\");\\n emit ProposalCreated(_chainId, _round, _proposalHash, _proposal, _creator);\\n }\\n\\n /**\\n * @dev Proposes for a global proposal.\\n *\\n * Emits the `GlobalProposalCreated` event.\\n *\\n */\\n function _proposeGlobal(\\n uint256 _expiryTimestamp,\\n GlobalProposal.TargetOption[] calldata _targetOptions,\\n uint256[] memory _values,\\n bytes[] memory _calldatas,\\n uint256[] memory _gasAmounts,\\n address _roninTrustedOrganizationContract,\\n address _gatewayContract,\\n address _creator\\n ) internal virtual returns (uint256 _round) {\\n GlobalProposal.GlobalProposalDetail memory _globalProposal = GlobalProposal.GlobalProposalDetail(\\n round[0] + 1,\\n _expiryTimestamp,\\n _targetOptions,\\n _values,\\n _calldatas,\\n _gasAmounts\\n );\\n Proposal.ProposalDetail memory _proposal = _globalProposal.into_proposal_detail(\\n _roninTrustedOrganizationContract,\\n _gatewayContract\\n );\\n _proposal.validate(_proposalExpiryDuration);\\n\\n bytes32 _proposalHash = _proposal.hash();\\n _round = _createVotingRound(0, _proposalHash, _expiryTimestamp);\\n emit GlobalProposalCreated(_round, _proposalHash, _proposal, _globalProposal.hash(), _globalProposal, _creator);\\n }\\n\\n /**\\n * @dev Proposes global proposal struct.\\n *\\n * Requirements:\\n * - The proposal nonce is equal to the new round.\\n *\\n * Emits the `GlobalProposalCreated` event.\\n *\\n */\\n function _proposeGlobalStruct(\\n GlobalProposal.GlobalProposalDetail memory _globalProposal,\\n address _roninTrustedOrganizationContract,\\n address _gatewayContract,\\n address _creator\\n ) internal virtual returns (Proposal.ProposalDetail memory _proposal, uint256 _round) {\\n _proposal = _globalProposal.into_proposal_detail(_roninTrustedOrganizationContract, _gatewayContract);\\n _proposal.validate(_proposalExpiryDuration);\\n\\n bytes32 _proposalHash = _proposal.hash();\\n _round = _createVotingRound(0, _proposalHash, _globalProposal.expiryTimestamp);\\n require(_round == _proposal.nonce, \\\"CoreGovernance: invalid proposal nonce\\\");\\n emit GlobalProposalCreated(_round, _proposalHash, _proposal, _globalProposal.hash(), _globalProposal, _creator);\\n }\\n\\n /**\\n * @dev Casts vote for the proposal with data and returns whether the voting is done.\\n *\\n * Requirements:\\n * - The proposal nonce is equal to the round.\\n * - The vote is not finalized.\\n * - The voter has not voted for the round.\\n *\\n * Emits the `ProposalVoted` event. Emits the `ProposalApproved`, `ProposalExecuted` or `ProposalRejected` once the\\n * proposal is approved, executed or rejected.\\n *\\n */\\n function _castVote(\\n Proposal.ProposalDetail memory _proposal,\\n Ballot.VoteType _support,\\n uint256 _minimumForVoteWeight,\\n uint256 _minimumAgainstVoteWeight,\\n address _voter,\\n Signature memory _signature,\\n uint256 _voterWeight\\n ) internal virtual returns (bool _done) {\\n uint256 _chainId = _proposal.chainId;\\n uint256 _round = _proposal.nonce;\\n ProposalVote storage _vote = vote[_chainId][_round];\\n\\n if (_tryDeleteExpiredVotingRound(_vote)) {\\n return true;\\n }\\n\\n require(round[_proposal.chainId] == _round, \\\"CoreGovernance: query for invalid proposal nonce\\\");\\n require(_vote.status == VoteStatus.Pending, \\\"CoreGovernance: the vote is finalized\\\");\\n if (_voted(_vote, _voter)) {\\n revert(string(abi.encodePacked(\\\"CoreGovernance: \\\", Strings.toHexString(uint160(_voter), 20), \\\" already voted\\\")));\\n }\\n\\n _vote.sig[_voter] = _signature;\\n emit ProposalVoted(_vote.hash, _voter, _support, _voterWeight);\\n\\n uint256 _forVoteWeight;\\n uint256 _againstVoteWeight;\\n if (_support == Ballot.VoteType.For) {\\n _vote.forVoteds.push(_voter);\\n _forVoteWeight = _vote.forVoteWeight += _voterWeight;\\n } else if (_support == Ballot.VoteType.Against) {\\n _vote.againstVoteds.push(_voter);\\n _againstVoteWeight = _vote.againstVoteWeight += _voterWeight;\\n } else {\\n revert(\\\"CoreGovernance: unsupported vote type\\\");\\n }\\n\\n if (_forVoteWeight >= _minimumForVoteWeight) {\\n _done = true;\\n _vote.status = VoteStatus.Approved;\\n emit ProposalApproved(_vote.hash);\\n _tryExecute(_vote, _proposal);\\n } else if (_againstVoteWeight >= _minimumAgainstVoteWeight) {\\n _done = true;\\n _vote.status = VoteStatus.Rejected;\\n emit ProposalRejected(_vote.hash);\\n }\\n }\\n\\n /**\\n * @dev Delete the expired proposal by its chainId and nonce, without creating a new proposal.\\n */\\n function _deleteExpiredVotingRound(uint256 _chainId, uint256 _round) internal {\\n ProposalVote storage _vote = vote[_chainId][_round];\\n _tryDeleteExpiredVotingRound(_vote);\\n }\\n\\n /**\\n * @dev When the contract is on Ronin chain, checks whether the proposal is expired and delete it if is expired.\\n */\\n function _tryDeleteExpiredVotingRound(ProposalVote storage _proposalVote) private returns (bool _isExpired) {\\n _isExpired =\\n _getChainType() == ChainType.RoninChain &&\\n _proposalVote.status == VoteStatus.Pending &&\\n _proposalVote.expiryTimestamp <= block.timestamp;\\n\\n if (_isExpired) {\\n emit ProposalExpired(_proposalVote.hash);\\n\\n for (uint256 _i; _i < _proposalVote.forVoteds.length; _i++) {\\n delete _proposalVote.sig[_proposalVote.forVoteds[_i]];\\n }\\n for (uint256 _i; _i < _proposalVote.againstVoteds.length; _i++) {\\n delete _proposalVote.sig[_proposalVote.againstVoteds[_i]];\\n }\\n delete _proposalVote.status;\\n delete _proposalVote.hash;\\n delete _proposalVote.againstVoteWeight;\\n delete _proposalVote.forVoteWeight;\\n delete _proposalVote.forVoteds;\\n delete _proposalVote.againstVoteds;\\n delete _proposalVote.expiryTimestamp;\\n }\\n }\\n\\n /**\\n * @dev Executes the proposal and update the vote status once the proposal is executable.\\n */\\n function _tryExecute(ProposalVote storage _vote, Proposal.ProposalDetail memory _proposal) internal {\\n if (_proposal.executable()) {\\n _vote.status = VoteStatus.Executed;\\n (bool[] memory _successCalls, bytes[] memory _returnDatas) = _proposal.execute();\\n emit ProposalExecuted(_vote.hash, _successCalls, _returnDatas);\\n }\\n }\\n\\n /**\\n * @dev Sets the expiry duration for a new proposal.\\n */\\n function _setProposalExpiryDuration(uint256 _expiryDuration) internal {\\n _proposalExpiryDuration = _expiryDuration;\\n }\\n\\n /**\\n * @dev Returns whether the voter casted for the proposal.\\n */\\n function _voted(ProposalVote storage _vote, address _voter) internal view returns (bool) {\\n return _vote.sig[_voter].r != 0;\\n }\\n\\n /**\\n * @dev Returns the expiry duration for a new proposal.\\n */\\n function _getProposalExpiryDuration() internal view returns (uint256) {\\n return _proposalExpiryDuration;\\n }\\n\\n /**\\n * @dev Returns total weight from validators.\\n */\\n function _getTotalWeights() internal view virtual returns (uint256);\\n\\n /**\\n * @dev Returns minimum vote to pass a proposal.\\n */\\n function _getMinimumVoteWeight() internal view virtual returns (uint256);\\n\\n /**\\n * @dev Returns current context is running on whether Ronin chain or on mainchain.\\n */\\n function _getChainType() internal view virtual returns (ChainType);\\n}\\n\",\"keccak256\":\"0xa5762fe73cec2493d7cc91d8aa62234f306d43ea7ceb8be0d49c2e3b87c4b5bf\",\"license\":\"MIT\"},\"contracts/extensions/sequential-governance/GovernanceProposal.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./CoreGovernance.sol\\\";\\n\\nabstract contract GovernanceProposal is CoreGovernance {\\n using Proposal for Proposal.ProposalDetail;\\n using GlobalProposal for GlobalProposal.GlobalProposalDetail;\\n\\n /**\\n * @dev Casts votes by signatures.\\n *\\n * Note: This method does not verify the proposal hash with the vote hash. Please consider checking it before.\\n *\\n */\\n function _castVotesBySignatures(\\n Proposal.ProposalDetail memory _proposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures,\\n bytes32 _forDigest,\\n bytes32 _againstDigest\\n ) internal {\\n require(_supports.length > 0 && _supports.length == _signatures.length, \\\"GovernanceProposal: invalid array length\\\");\\n uint256 _minimumForVoteWeight = _getMinimumVoteWeight();\\n uint256 _minimumAgainstVoteWeight = _getTotalWeights() - _minimumForVoteWeight + 1;\\n\\n address _lastSigner;\\n address _signer;\\n Signature memory _sig;\\n bool _hasValidVotes;\\n for (uint256 _i; _i < _signatures.length; _i++) {\\n _sig = _signatures[_i];\\n\\n if (_supports[_i] == Ballot.VoteType.For) {\\n _signer = ECDSA.recover(_forDigest, _sig.v, _sig.r, _sig.s);\\n } else if (_supports[_i] == Ballot.VoteType.Against) {\\n _signer = ECDSA.recover(_againstDigest, _sig.v, _sig.r, _sig.s);\\n } else {\\n revert(\\\"GovernanceProposal: query for unsupported vote type\\\");\\n }\\n\\n require(_lastSigner < _signer, \\\"GovernanceProposal: invalid order\\\");\\n _lastSigner = _signer;\\n\\n uint256 _weight = _getWeight(_signer);\\n if (_weight > 0) {\\n _hasValidVotes = true;\\n if (\\n _castVote(_proposal, _supports[_i], _minimumForVoteWeight, _minimumAgainstVoteWeight, _signer, _sig, _weight)\\n ) {\\n return;\\n }\\n }\\n }\\n\\n require(_hasValidVotes, \\\"GovernanceProposal: invalid signatures\\\");\\n }\\n\\n /**\\n * @dev Proposes a proposal struct and casts votes by signature.\\n */\\n function _proposeProposalStructAndCastVotes(\\n Proposal.ProposalDetail calldata _proposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures,\\n bytes32 _domainSeparator,\\n address _creator\\n ) internal {\\n _proposeProposalStruct(_proposal, _creator);\\n bytes32 _proposalHash = _proposal.hash();\\n _castVotesBySignatures(\\n _proposal,\\n _supports,\\n _signatures,\\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_proposalHash, Ballot.VoteType.For)),\\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_proposalHash, Ballot.VoteType.Against))\\n );\\n }\\n\\n /**\\n * @dev Proposes a proposal struct and casts votes by signature.\\n */\\n function _castProposalBySignatures(\\n Proposal.ProposalDetail calldata _proposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures,\\n bytes32 _domainSeparator\\n ) internal {\\n bytes32 _proposalHash = _proposal.hash();\\n require(\\n vote[_proposal.chainId][_proposal.nonce].hash == _proposalHash,\\n \\\"GovernanceAdmin: cast vote for invalid proposal\\\"\\n );\\n _castVotesBySignatures(\\n _proposal,\\n _supports,\\n _signatures,\\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_proposalHash, Ballot.VoteType.For)),\\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_proposalHash, Ballot.VoteType.Against))\\n );\\n }\\n\\n /**\\n * @dev Proposes and votes by signature.\\n */\\n function _proposeGlobalProposalStructAndCastVotes(\\n GlobalProposal.GlobalProposalDetail calldata _globalProposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures,\\n bytes32 _domainSeparator,\\n address _roninTrustedOrganizationContract,\\n address _gatewayContract,\\n address _creator\\n ) internal returns (Proposal.ProposalDetail memory _proposal) {\\n (_proposal, ) = _proposeGlobalStruct(\\n _globalProposal,\\n _roninTrustedOrganizationContract,\\n _gatewayContract,\\n _creator\\n );\\n bytes32 _globalProposalHash = _globalProposal.hash();\\n _castVotesBySignatures(\\n _proposal,\\n _supports,\\n _signatures,\\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_globalProposalHash, Ballot.VoteType.For)),\\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_globalProposalHash, Ballot.VoteType.Against))\\n );\\n }\\n\\n /**\\n * @dev Proposes a global proposal struct and casts votes by signature.\\n */\\n function _castGlobalProposalBySignatures(\\n GlobalProposal.GlobalProposalDetail calldata _globalProposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures,\\n bytes32 _domainSeparator,\\n address _roninTrustedOrganizationContract,\\n address _gatewayContract\\n ) internal {\\n Proposal.ProposalDetail memory _proposal = _globalProposal.into_proposal_detail(\\n _roninTrustedOrganizationContract,\\n _gatewayContract\\n );\\n bytes32 _globalProposalHash = _globalProposal.hash();\\n require(vote[0][_proposal.nonce].hash == _proposal.hash(), \\\"GovernanceAdmin: cast vote for invalid proposal\\\");\\n _castVotesBySignatures(\\n _proposal,\\n _supports,\\n _signatures,\\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_globalProposalHash, Ballot.VoteType.For)),\\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_globalProposalHash, Ballot.VoteType.Against))\\n );\\n }\\n\\n /**\\n * @dev Returns the weight of a governor.\\n */\\n function _getWeight(address _governor) internal view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xe75f250d5c7da8b2c8892b417ba0bc7e14542718802c00f4df556a663d8f6ae7\",\"license\":\"MIT\"},\"contracts/interfaces/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IBridge {\\n /**\\n * @dev Replaces the old bridge operator list by the new one.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n *\\n * Emitted the event `BridgeOperatorsReplaced`.\\n *\\n */\\n function replaceBridgeOperators(address[] calldata) external;\\n\\n /**\\n * @dev Returns the bridge operator list.\\n */\\n function getBridgeOperators() external view returns (address[] memory);\\n}\\n\",\"keccak256\":\"0x614db701e54383b7d0a749bc9b0d2da95d42652cd673499bf71e25096548b96e\",\"license\":\"MIT\"},\"contracts/interfaces/IQuorum.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IQuorum {\\n /// @dev Emitted when the threshold is updated\\n event ThresholdUpdated(\\n uint256 indexed nonce,\\n uint256 indexed numerator,\\n uint256 indexed denominator,\\n uint256 previousNumerator,\\n uint256 previousDenominator\\n );\\n\\n /**\\n * @dev Returns the threshold.\\n */\\n function getThreshold() external view returns (uint256 _num, uint256 _denom);\\n\\n /**\\n * @dev Checks whether the `_voteWeight` passes the threshold.\\n */\\n function checkThreshold(uint256 _voteWeight) external view returns (bool);\\n\\n /**\\n * @dev Returns the minimum vote weight to pass the threshold.\\n */\\n function minimumVoteWeight() external view returns (uint256);\\n\\n /**\\n * @dev Sets the threshold.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n *\\n * Emits the `ThresholdUpdated` event.\\n *\\n */\\n function setThreshold(uint256 _numerator, uint256 _denominator)\\n external\\n returns (uint256 _previousNum, uint256 _previousDenom);\\n}\\n\",\"keccak256\":\"0x10f3b360430e6d03773c9959f54cbed6fb0346069645c05b05ef50cfb19f3753\",\"license\":\"MIT\"},\"contracts/interfaces/IRoninGovernanceAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IRoninGovernanceAdmin {\\n /**\\n * @dev Returns the last voted block of the bridge voter.\\n */\\n function lastVotedBlock(address _bridgeVoter) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0xaf8bbda9f65a09444b3ebbcd19a62e39bf8711047224744f86439db6f42551b2\",\"license\":\"MIT\"},\"contracts/interfaces/IRoninTrustedOrganization.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"./IQuorum.sol\\\";\\n\\ninterface IRoninTrustedOrganization is IQuorum {\\n struct TrustedOrganization {\\n // Address of the validator that produces block, e.g. block.coinbase. This is so-called validator address.\\n address consensusAddr;\\n // Address to voting proposal\\n address governor;\\n // Address to voting bridge operators\\n address bridgeVoter;\\n // Its Weight\\n uint256 weight;\\n // The block that the organization was added\\n uint256 addedBlock;\\n }\\n\\n /// @dev Emitted when the trusted organization is added.\\n event TrustedOrganizationsAdded(TrustedOrganization[] orgs);\\n /// @dev Emitted when the trusted organization is updated.\\n event TrustedOrganizationsUpdated(TrustedOrganization[] orgs);\\n /// @dev Emitted when the trusted organization is removed.\\n event TrustedOrganizationsRemoved(address[] orgs);\\n\\n /**\\n * @dev Adds a list of addresses into the trusted organization.\\n *\\n * Requirements:\\n * - The weights should larger than 0.\\n * - The method caller is admin.\\n * - The field `addedBlock` should be blank.\\n *\\n * Emits the event `TrustedOrganizationAdded` once an organization is added.\\n *\\n */\\n function addTrustedOrganizations(TrustedOrganization[] calldata) external;\\n\\n /**\\n * @dev Updates weights for a list of existent trusted organization.\\n *\\n * Requirements:\\n * - The weights should larger than 0.\\n * - The method caller is admin.\\n *\\n * Emits the `TrustedOrganizationUpdated` event.\\n *\\n */\\n function updateTrustedOrganizations(TrustedOrganization[] calldata _list) external;\\n\\n /**\\n * @dev Removes a list of addresses from the trusted organization.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n *\\n * Emits the event `TrustedOrganizationRemoved` once an organization is removed.\\n *\\n * @param _consensusAddrs The list of consensus addresses linked to corresponding trusted organization that to be removed.\\n */\\n function removeTrustedOrganizations(address[] calldata _consensusAddrs) external;\\n\\n /**\\n * @dev Returns total weights.\\n */\\n function totalWeights() external view returns (uint256);\\n\\n /**\\n * @dev Returns the weight of a consensus.\\n */\\n function getConsensusWeight(address _consensusAddr) external view returns (uint256);\\n\\n /**\\n * @dev Returns the weight of a governor.\\n */\\n function getGovernorWeight(address _governor) external view returns (uint256);\\n\\n /**\\n * @dev Returns the weight of a bridge voter.\\n */\\n function getBridgeVoterWeight(address _addr) external view returns (uint256);\\n\\n /**\\n * @dev Returns the weights of a list of consensus addresses.\\n */\\n function getConsensusWeights(address[] calldata _list) external view returns (uint256[] memory);\\n\\n /**\\n * @dev Returns the weights of a list of governor addresses.\\n */\\n function getGovernorWeights(address[] calldata _list) external view returns (uint256[] memory);\\n\\n /**\\n * @dev Returns the weights of a list of bridge voter addresses.\\n */\\n function getBridgeVoterWeights(address[] calldata _list) external view returns (uint256[] memory);\\n\\n /**\\n * @dev Returns total weights of the consensus list.\\n */\\n function sumConsensusWeights(address[] calldata _list) external view returns (uint256 _res);\\n\\n /**\\n * @dev Returns total weights of the governor list.\\n */\\n function sumGovernorWeights(address[] calldata _list) external view returns (uint256 _res);\\n\\n /**\\n * @dev Returns total weights of the bridge voter list.\\n */\\n function sumBridgeVoterWeights(address[] calldata _list) external view returns (uint256 _res);\\n\\n /**\\n * @dev Returns the trusted organization at `_index`.\\n */\\n function getTrustedOrganizationAt(uint256 _index) external view returns (TrustedOrganization memory);\\n\\n /**\\n * @dev Returns the number of trusted organizations.\\n */\\n function countTrustedOrganizations() external view returns (uint256);\\n\\n /**\\n * @dev Returns all of the trusted organizations.\\n */\\n function getAllTrustedOrganizations() external view returns (TrustedOrganization[] memory);\\n\\n /**\\n * @dev Returns the trusted organization by consensus address.\\n *\\n * Reverts once the consensus address is non-existent.\\n */\\n function getTrustedOrganization(address _consensusAddr) external view returns (TrustedOrganization memory);\\n}\\n\",\"keccak256\":\"0x1edb7a3f5d340e7efc141cb8d94c5499954dec869f026d3998ad92cbc714d604\",\"license\":\"MIT\"},\"contracts/interfaces/collections/IHasBridgeContract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface IHasBridgeContract {\\n /// @dev Emitted when the bridge contract is updated.\\n event BridgeContractUpdated(address);\\n\\n /**\\n * @dev Returns the bridge contract.\\n */\\n function bridgeContract() external view returns (address);\\n\\n /**\\n * @dev Sets the bridge contract.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n * - The new address is a contract.\\n *\\n * Emits the event `BridgeContractUpdated`.\\n *\\n */\\n function setBridgeContract(address) external;\\n}\\n\",\"keccak256\":\"0xb1c239a3987c93db20b65bb80f165861bc83a186fb8d5a1c17c5ad06cfb395a8\",\"license\":\"MIT\"},\"contracts/interfaces/collections/IHasRoninTrustedOrganizationContract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface IHasRoninTrustedOrganizationContract {\\n /// @dev Emitted when the ronin trusted organization contract is updated.\\n event RoninTrustedOrganizationContractUpdated(address);\\n\\n /**\\n * @dev Returns the ronin trusted organization contract.\\n */\\n function roninTrustedOrganizationContract() external view returns (address);\\n\\n /**\\n * @dev Sets the ronin trusted organization contract.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n * - The new address is a contract.\\n *\\n * Emits the event `RoninTrustedOrganizationContractUpdated`.\\n *\\n */\\n function setRoninTrustedOrganizationContract(address) external;\\n}\\n\",\"keccak256\":\"0x8ec2782f28a2c41d8feee0c5f213ac66e327c3757eab8d85a09104f21587ff10\",\"license\":\"MIT\"},\"contracts/interfaces/consumers/ChainTypeConsumer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ChainTypeConsumer {\\n enum ChainType {\\n RoninChain,\\n Mainchain\\n }\\n}\\n\",\"keccak256\":\"0xe0d20e00c8d237f8e0fb881abf1ff1ef114173bcb428f06f689c581666a22db7\",\"license\":\"MIT\"},\"contracts/interfaces/consumers/SignatureConsumer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface SignatureConsumer {\\n struct Signature {\\n uint8 v;\\n bytes32 r;\\n bytes32 s;\\n }\\n}\\n\",\"keccak256\":\"0xd370e350722067097dec1a5c31bda6e47e83417fa5c3288293bb910028cd136b\",\"license\":\"MIT\"},\"contracts/interfaces/consumers/VoteStatusConsumer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface VoteStatusConsumer {\\n enum VoteStatus {\\n Pending,\\n Approved,\\n Executed,\\n Rejected\\n }\\n}\\n\",\"keccak256\":\"0xc2f5e7cf4fdc18b990b3829e4ba479cd7aa0c5ea553a39dc3f1bf2e9aaed38df\",\"license\":\"MIT\"},\"contracts/interfaces/consumers/WeightedAddressConsumer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface WeightedAddressConsumer {\\n struct WeightedAddress {\\n address addr;\\n uint256 weight;\\n }\\n}\\n\",\"keccak256\":\"0xc141bda51591ca368cf9263df1b10cdb298583a4fe5104160eeaa4cf39f32763\",\"license\":\"MIT\"},\"contracts/libraries/Ballot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\n\\nlibrary Ballot {\\n using ECDSA for bytes32;\\n\\n enum VoteType {\\n For,\\n Against\\n }\\n\\n // keccak256(\\\"Ballot(bytes32 proposalHash,uint8 support)\\\");\\n bytes32 public constant BALLOT_TYPEHASH = 0xd900570327c4c0df8dd6bdd522b7da7e39145dd049d2fd4602276adcd511e3c2;\\n\\n function hash(bytes32 _proposalHash, VoteType _support) internal pure returns (bytes32) {\\n return keccak256(abi.encode(BALLOT_TYPEHASH, _proposalHash, _support));\\n }\\n}\\n\",\"keccak256\":\"0x28a0192db886307f30ada203bdb902749ee3f30d42710de4eaf303cba23c32c2\",\"license\":\"MIT\"},\"contracts/libraries/BridgeOperatorsBallot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../interfaces/consumers/WeightedAddressConsumer.sol\\\";\\n\\nlibrary BridgeOperatorsBallot {\\n // keccak256(\\\"BridgeOperatorsBallot(uint256 period,address[] operators)\\\");\\n bytes32 public constant BRIDGE_OPERATORS_BALLOT_TYPEHASH =\\n 0xeea5e3908ac28cbdbbce8853e49444c558a0a03597e98ef19e6ff86162ed9ae3;\\n\\n /**\\n * @dev Returns hash of the ballot.\\n */\\n function hash(uint256 _period, address[] memory _operators) internal pure returns (bytes32) {\\n bytes32 _operatorsHash;\\n assembly {\\n _operatorsHash := keccak256(add(_operators, 32), mul(mload(_operators), 32))\\n }\\n\\n return keccak256(abi.encode(BRIDGE_OPERATORS_BALLOT_TYPEHASH, _period, _operatorsHash));\\n }\\n}\\n\",\"keccak256\":\"0xe90d38a54b9029912a3e58f58a595da8ea285d3775d1ad798651e94f7ec83ab6\",\"license\":\"MIT\"},\"contracts/libraries/GlobalProposal.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./Proposal.sol\\\";\\n\\nlibrary GlobalProposal {\\n enum TargetOption {\\n RoninTrustedOrganizationContract,\\n GatewayContract\\n }\\n\\n struct GlobalProposalDetail {\\n // Nonce to make sure proposals are executed in order\\n uint256 nonce;\\n uint256 expiryTimestamp;\\n TargetOption[] targetOptions;\\n uint256[] values;\\n bytes[] calldatas;\\n uint256[] gasAmounts;\\n }\\n\\n // keccak256(\\\"GlobalProposalDetail(uint256 nonce,uint256 expiryTimestamp,uint8[] targetOptions,uint256[] values,bytes[] calldatas,uint256[] gasAmounts)\\\");\\n bytes32 public constant TYPE_HASH = 0x1463f426c05aff2c1a7a0957a71c9898bc8b47142540538e79ee25ee91141350;\\n\\n /**\\n * @dev Returns struct hash of the proposal.\\n */\\n function hash(GlobalProposalDetail memory _proposal) internal pure returns (bytes32) {\\n bytes32 _targetsHash;\\n bytes32 _valuesHash;\\n bytes32 _calldatasHash;\\n bytes32 _gasAmountsHash;\\n\\n uint256[] memory _values = _proposal.values;\\n TargetOption[] memory _targets = _proposal.targetOptions;\\n bytes32[] memory _calldataHashList = new bytes32[](_proposal.calldatas.length);\\n uint256[] memory _gasAmounts = _proposal.gasAmounts;\\n\\n for (uint256 _i; _i < _calldataHashList.length; _i++) {\\n _calldataHashList[_i] = keccak256(_proposal.calldatas[_i]);\\n }\\n\\n assembly {\\n _targetsHash := keccak256(add(_targets, 32), mul(mload(_targets), 32))\\n _valuesHash := keccak256(add(_values, 32), mul(mload(_values), 32))\\n _calldatasHash := keccak256(add(_calldataHashList, 32), mul(mload(_calldataHashList), 32))\\n _gasAmountsHash := keccak256(add(_gasAmounts, 32), mul(mload(_gasAmounts), 32))\\n }\\n\\n return\\n keccak256(\\n abi.encode(\\n TYPE_HASH,\\n _proposal.nonce,\\n _proposal.expiryTimestamp,\\n _targetsHash,\\n _valuesHash,\\n _calldatasHash,\\n _gasAmountsHash\\n )\\n );\\n }\\n\\n /**\\n * @dev Converts into the normal proposal.\\n */\\n function into_proposal_detail(\\n GlobalProposalDetail memory _proposal,\\n address _roninTrustedOrganizationContract,\\n address _gatewayContract\\n ) internal pure returns (Proposal.ProposalDetail memory _detail) {\\n _detail.nonce = _proposal.nonce;\\n _detail.expiryTimestamp = _proposal.expiryTimestamp;\\n _detail.chainId = 0;\\n _detail.targets = new address[](_proposal.targetOptions.length);\\n _detail.values = _proposal.values;\\n _detail.calldatas = _proposal.calldatas;\\n _detail.gasAmounts = _proposal.gasAmounts;\\n\\n for (uint256 _i; _i < _proposal.targetOptions.length; _i++) {\\n if (_proposal.targetOptions[_i] == TargetOption.GatewayContract) {\\n _detail.targets[_i] = _gatewayContract;\\n } else if (_proposal.targetOptions[_i] == TargetOption.RoninTrustedOrganizationContract) {\\n _detail.targets[_i] = _roninTrustedOrganizationContract;\\n } else {\\n revert(\\\"GlobalProposal: unsupported target\\\");\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4749e811eebe029ac572b48e5c755bc852cc74e8234c5243a57f7536c3ed00e0\",\"license\":\"MIT\"},\"contracts/libraries/Proposal.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nlibrary Proposal {\\n struct ProposalDetail {\\n // Nonce to make sure proposals are executed in order\\n uint256 nonce;\\n // Value 0: all chain should run this proposal\\n // Other values: only specifc chain has to execute\\n uint256 chainId;\\n uint256 expiryTimestamp;\\n address[] targets;\\n uint256[] values;\\n bytes[] calldatas;\\n uint256[] gasAmounts;\\n }\\n\\n // keccak256(\\\"ProposalDetail(uint256 nonce,uint256 chainId,uint256 expiryTimestamp,address[] targets,uint256[] values,bytes[] calldatas,uint256[] gasAmounts)\\\");\\n bytes32 public constant TYPE_HASH = 0xd051578048e6ff0bbc9fca3b65a42088dbde10f36ca841de566711087ad9b08a;\\n\\n /**\\n * @dev Validates the proposal.\\n */\\n function validate(ProposalDetail memory _proposal, uint256 _maxExpiryDuration) internal view {\\n require(\\n _proposal.targets.length > 0 &&\\n _proposal.targets.length == _proposal.values.length &&\\n _proposal.targets.length == _proposal.calldatas.length &&\\n _proposal.targets.length == _proposal.gasAmounts.length,\\n \\\"Proposal: invalid array length\\\"\\n );\\n require(_proposal.expiryTimestamp <= block.timestamp + _maxExpiryDuration, \\\"Proposal: invalid expiry timestamp\\\");\\n }\\n\\n /**\\n * @dev Returns struct hash of the proposal.\\n */\\n function hash(ProposalDetail memory _proposal) internal pure returns (bytes32) {\\n bytes32 _targetsHash;\\n bytes32 _valuesHash;\\n bytes32 _calldatasHash;\\n bytes32 _gasAmountsHash;\\n\\n uint256[] memory _values = _proposal.values;\\n address[] memory _targets = _proposal.targets;\\n bytes32[] memory _calldataHashList = new bytes32[](_proposal.calldatas.length);\\n uint256[] memory _gasAmounts = _proposal.gasAmounts;\\n\\n for (uint256 _i; _i < _calldataHashList.length; _i++) {\\n _calldataHashList[_i] = keccak256(_proposal.calldatas[_i]);\\n }\\n\\n assembly {\\n _targetsHash := keccak256(add(_targets, 32), mul(mload(_targets), 32))\\n _valuesHash := keccak256(add(_values, 32), mul(mload(_values), 32))\\n _calldatasHash := keccak256(add(_calldataHashList, 32), mul(mload(_calldataHashList), 32))\\n _gasAmountsHash := keccak256(add(_gasAmounts, 32), mul(mload(_gasAmounts), 32))\\n }\\n\\n return\\n keccak256(\\n abi.encode(\\n TYPE_HASH,\\n _proposal.nonce,\\n _proposal.chainId,\\n _proposal.expiryTimestamp,\\n _targetsHash,\\n _valuesHash,\\n _calldatasHash,\\n _gasAmountsHash\\n )\\n );\\n }\\n\\n /**\\n * @dev Returns whether the proposal is executable for the current chain.\\n *\\n * @notice Does not check whether the call result is successful or not. Please use `execute` instead.\\n *\\n */\\n function executable(ProposalDetail memory _proposal) internal view returns (bool _result) {\\n return _proposal.chainId == 0 || _proposal.chainId == block.chainid;\\n }\\n\\n /**\\n * @dev Executes the proposal.\\n */\\n function execute(ProposalDetail memory _proposal)\\n internal\\n returns (bool[] memory _successCalls, bytes[] memory _returnDatas)\\n {\\n require(executable(_proposal), \\\"Proposal: query for invalid chainId\\\");\\n _successCalls = new bool[](_proposal.targets.length);\\n _returnDatas = new bytes[](_proposal.targets.length);\\n for (uint256 _i = 0; _i < _proposal.targets.length; ++_i) {\\n require(gasleft() > _proposal.gasAmounts[_i], \\\"Proposal: insufficient gas\\\");\\n\\n (_successCalls[_i], _returnDatas[_i]) = _proposal.targets[_i].call{\\n value: _proposal.values[_i],\\n gas: _proposal.gasAmounts[_i]\\n }(_proposal.calldatas[_i]);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x96bf9eaea9a87a5eceed026a6eaedc74cf5dde6760f7e969d5b5974dad43ff80\",\"license\":\"MIT\"},\"contracts/ronin/RoninGovernanceAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"../extensions/isolated-governance/bridge-operator-governance/BOsGovernanceProposal.sol\\\";\\nimport \\\"../extensions/sequential-governance/GovernanceProposal.sol\\\";\\nimport \\\"../extensions/GovernanceAdmin.sol\\\";\\nimport \\\"../interfaces/IBridge.sol\\\";\\n\\ncontract RoninGovernanceAdmin is GovernanceAdmin, GovernanceProposal, BOsGovernanceProposal {\\n /// @dev Emitted when the bridge operators are approved.\\n event BridgeOperatorsApproved(uint256 _period, address[] _operators);\\n\\n modifier onlyGovernor() {\\n require(_getWeight(msg.sender) > 0, \\\"GovernanceAdmin: sender is not governor\\\");\\n _;\\n }\\n\\n constructor(\\n address _roninTrustedOrganizationContract,\\n address _bridgeContract,\\n uint256 _proposalExpiryDuration\\n ) GovernanceAdmin(_roninTrustedOrganizationContract, _bridgeContract, _proposalExpiryDuration) {}\\n\\n /**\\n * @dev Returns the voted signatures for the proposals.\\n *\\n */\\n function getProposalSignatures(uint256 _chainId, uint256 _round)\\n external\\n view\\n returns (Ballot.VoteType[] memory _supports, Signature[] memory _signatures)\\n {\\n ProposalVote storage _vote = vote[_chainId][_round];\\n\\n uint256 _forLength = _vote.forVoteds.length;\\n uint256 _againstLength = _vote.againstVoteds.length;\\n uint256 _voterLength = _forLength + _againstLength;\\n\\n _supports = new Ballot.VoteType[](_voterLength);\\n _signatures = new Signature[](_voterLength);\\n for (uint256 _i; _i < _forLength; _i++) {\\n _supports[_i] = Ballot.VoteType.For;\\n _signatures[_i] = vote[_chainId][_round].sig[_vote.forVoteds[_i]];\\n }\\n for (uint256 _i; _i < _againstLength; _i++) {\\n _supports[_i + _forLength] = Ballot.VoteType.Against;\\n _signatures[_i + _forLength] = vote[_chainId][_round].sig[_vote.againstVoteds[_i]];\\n }\\n }\\n\\n /**\\n * @dev Returns the voted signatures for bridge operators at a specific period.\\n *\\n * Note: Does not verify whether the voter casted vote for the proposal and the returned signature can be empty.\\n * Please consider filtering for empty signatures after calling this function.\\n *\\n */\\n function getBridgeOperatorVotingSignatures(uint256 _period, address[] calldata _voters)\\n external\\n view\\n returns (Signature[] memory _signatures)\\n {\\n _signatures = new Signature[](_voters.length);\\n for (uint256 _i; _i < _voters.length; _i++) {\\n _signatures[_i] = _votingSig[_period][_voters[_i]];\\n }\\n }\\n\\n /**\\n * @dev Returns whether the voter `_voter` casted vote for the proposal.\\n */\\n function proposalVoted(\\n uint256 _chainId,\\n uint256 _round,\\n address _voter\\n ) external view returns (bool) {\\n return _voted(vote[_chainId][_round], _voter);\\n }\\n\\n /**\\n * @dev Returns whether the voter `_voter` casted vote for bridge operators at a specific period.\\n */\\n function bridgeOperatorsVoted(uint256 _period, address _voter) external view returns (bool) {\\n return _voted(_vote[_period], _voter);\\n }\\n\\n /**\\n * @dev See `CoreGovernance-_proposeProposal`.\\n *\\n * Requirements:\\n * - The method caller is governor.\\n *\\n */\\n function propose(\\n uint256 _chainId,\\n uint256 _expiryTimestamp,\\n address[] calldata _targets,\\n uint256[] calldata _values,\\n bytes[] calldata _calldatas,\\n uint256[] calldata _gasAmounts\\n ) external onlyGovernor {\\n _proposeProposal(_chainId, _expiryTimestamp, _targets, _values, _calldatas, _gasAmounts, msg.sender);\\n }\\n\\n /**\\n * @dev See `GovernanceProposal-_proposeProposalStructAndCastVotes`.\\n *\\n * Requirements:\\n * - The method caller is governor.\\n *\\n */\\n function proposeProposalStructAndCastVotes(\\n Proposal.ProposalDetail calldata _proposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures\\n ) external onlyGovernor {\\n _proposeProposalStructAndCastVotes(_proposal, _supports, _signatures, DOMAIN_SEPARATOR, msg.sender);\\n }\\n\\n /**\\n * @dev See `GovernanceProposal-_castProposalBySignatures`.\\n */\\n function castProposalBySignatures(\\n Proposal.ProposalDetail calldata _proposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures\\n ) external {\\n _castProposalBySignatures(_proposal, _supports, _signatures, DOMAIN_SEPARATOR);\\n }\\n\\n /**\\n * @dev See `CoreGovernance-_proposeGlobal`.\\n *\\n * Requirements:\\n * - The method caller is governor.\\n *\\n */\\n function proposeGlobal(\\n uint256 _expiryTimestamp,\\n GlobalProposal.TargetOption[] calldata _targetOptions,\\n uint256[] calldata _values,\\n bytes[] calldata _calldatas,\\n uint256[] calldata _gasAmounts\\n ) external onlyGovernor {\\n _proposeGlobal(\\n _expiryTimestamp,\\n _targetOptions,\\n _values,\\n _calldatas,\\n _gasAmounts,\\n roninTrustedOrganizationContract(),\\n bridgeContract(),\\n msg.sender\\n );\\n }\\n\\n /**\\n * @dev See `GovernanceProposal-_proposeGlobalProposalStructAndCastVotes`.\\n *\\n * Requirements:\\n * - The method caller is governor.\\n *\\n */\\n function proposeGlobalProposalStructAndCastVotes(\\n GlobalProposal.GlobalProposalDetail calldata _globalProposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures\\n ) external onlyGovernor {\\n _proposeGlobalProposalStructAndCastVotes(\\n _globalProposal,\\n _supports,\\n _signatures,\\n DOMAIN_SEPARATOR,\\n roninTrustedOrganizationContract(),\\n bridgeContract(),\\n msg.sender\\n );\\n }\\n\\n /**\\n * @dev See `GovernanceProposal-_castGlobalProposalBySignatures`.\\n */\\n function castGlobalProposalBySignatures(\\n GlobalProposal.GlobalProposalDetail calldata _globalProposal,\\n Ballot.VoteType[] calldata _supports,\\n Signature[] calldata _signatures\\n ) external {\\n _castGlobalProposalBySignatures(\\n _globalProposal,\\n _supports,\\n _signatures,\\n DOMAIN_SEPARATOR,\\n roninTrustedOrganizationContract(),\\n bridgeContract()\\n );\\n }\\n\\n /**\\n * @dev See `CoreGovernance-_deleteExpiredProposal`\\n */\\n function deleteExpired(uint256 chainId, uint256 round) external {\\n _deleteExpiredVotingRound(chainId, round);\\n }\\n\\n /**\\n * @dev See `BOsGovernanceProposal-_castVotesBySignatures`.\\n */\\n function voteBridgeOperatorsBySignatures(\\n uint256 _period,\\n address[] calldata _operators,\\n Signature[] calldata _signatures\\n ) external {\\n _castVotesBySignatures(_operators, _signatures, _period, _getMinimumVoteWeight(), DOMAIN_SEPARATOR);\\n IsolatedVote storage _v = _vote[_period];\\n if (_v.status == VoteStatus.Approved) {\\n _lastSyncedPeriod = _period;\\n emit BridgeOperatorsApproved(_period, _operators);\\n _v.status = VoteStatus.Executed;\\n }\\n }\\n\\n /**\\n * @inheritdoc GovernanceProposal\\n */\\n function _getWeight(address _governor) internal view virtual override returns (uint256) {\\n (bool _success, bytes memory _returndata) = roninTrustedOrganizationContract().staticcall(\\n abi.encodeWithSelector(\\n // TransparentUpgradeableProxyV2.functionDelegateCall.selector,\\n 0x4bb5274a,\\n abi.encodeWithSelector(IRoninTrustedOrganization.getGovernorWeight.selector, _governor)\\n )\\n );\\n require(_success, \\\"GovernanceAdmin: proxy call `getGovernorWeight(address)` failed\\\");\\n return abi.decode(_returndata, (uint256));\\n }\\n\\n /**\\n * @inheritdoc BOsGovernanceProposal\\n */\\n function _getBridgeVoterWeight(address _governor) internal view virtual override returns (uint256) {\\n (bool _success, bytes memory _returndata) = roninTrustedOrganizationContract().staticcall(\\n abi.encodeWithSelector(\\n // TransparentUpgradeableProxyV2.functionDelegateCall.selector,\\n 0x4bb5274a,\\n abi.encodeWithSelector(IRoninTrustedOrganization.getBridgeVoterWeight.selector, _governor)\\n )\\n );\\n require(_success, \\\"GovernanceAdmin: proxy call `getBridgeVoterWeight(address)` failed\\\");\\n return abi.decode(_returndata, (uint256));\\n }\\n\\n /**\\n * @dev See {CoreGovernance-_getChainType}\\n */\\n function _getChainType() internal pure override returns (ChainType) {\\n return ChainType.RoninChain;\\n }\\n}\\n\",\"keccak256\":\"0xb56e369ff4035b55e8f29b0162e729993d47abff785f25e58aabc1a50720f1d5\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b5060405162004d6c38038062004d6c833981016040819052620000349162000288565b828282806200004281600255565b50604080516020808201839052601660608301527f524f4e494e5f474f5645524e414e43455f41444d494e000000000000000000006080808401919091526107e4838501528351808403909101815260a0830184528051908201207f599a80fcaa47b95e2323ab4d34d34e0cc9feda4b843edafcc30c7bdf60ea15bf60c08401527f7e7935007966eb860f4a2ee3dcc9fd53fb3205ce2aa86b0126d4893d4d4c14b960e08401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6610100840152610120808401919091528351808403909101815261014090920190925280519101207ff8704f8860d9e985bf6c52ec4738bd10fe31487599b36c0944f746ea09dc256b14620001a55760405162461bcd60e51b815260206004820152601f60248201527f476f7665726e616e636541646d696e3a20696e76616c696420646f6d61696e00604482015260640160405180910390fd5b620001b083620001c7565b620001bb826200021c565b505050505050620002c9565b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527ffd6f5f93d69a07c593a09be0b208bff13ab4ffd6017df3b33433d63bdc59b4d7906020015b60405180910390a150565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5cbd8a0bb00196365d5eb3457c6734e7f06666c3c78e5469b4c9deec7edae0489060200162000211565b80516001600160a01b03811681146200028357600080fd5b919050565b6000806000606084860312156200029e57600080fd5b620002a9846200026b565b9250620002b9602085016200026b565b9150604084015190509250925092565b614a9380620002d96000396000f3fe608060405234801561001057600080fd5b50600436106101725760003560e01c80633644e515116100de578063a1819f9a11610097578063bc96180b11610071578063bc96180b146103c9578063cd596583146103d1578063f3b7dead146103e2578063fb4f6371146103f557600080fd5b8063a1819f9a14610348578063b384abef1461035b578063b5e337de146103b657600080fd5b80633644e515146102c05780635511cde1146102d557806356e237e8146102e65780637eff275e146102f9578063988ef53c1461030c5780639a7d33821461033557600080fd5b8063204e1c7a11610130578063204e1c7a1461020e5780632c5e6520146102395780632e96a6fb1461024c5780632faf925d1461025f578063332635be1461027257806334d5f37b1461029257600080fd5b80624054b814610177578063055c68891461018c57806309fcd8c7146101b45780630b26cf66146101c75780630b881830146101da5780631c905e39146101ed575b600080fd5b61018a61018536600461396d565b610408565b005b61019f61019a366004613a1e565b61045d565b60405190151581526020015b60405180910390f35b61018a6101c2366004613a4e565b61048f565b61018a6101d5366004613b1d565b610558565b61018a6101e836600461396d565b6105ad565b6102006101fb366004613b3a565b6105c9565b6040516101ab929190613bd6565b61022161021c366004613b1d565b6108c7565b6040516001600160a01b0390911681526020016101ab565b61019f610247366004613c36565b6109b9565b61018a61025a366004613c6f565b6109ef565b61018a61026d366004613c88565b610a17565b610285610280366004613ccb565b610a51565b6040516101ab9190613d16565b6102b26102a0366004613c6f565b60006020819052908152604090205481565b6040519081526020016101ab565b6102b2600080516020614a3e83398151915281565b6003546001600160a01b0316610221565b61018a6102f4366004613d29565b610b82565b61018a610307366004613d5f565b610c26565b6102b261031a366004613b1d565b6001600160a01b031660009081526007602052604090205490565b61018a610343366004613b3a565b610d57565b61018a610356366004613d8d565b610d65565b6103a5610369366004613b3a565b600160208181526000938452604080852090915291835291208054918101546002820154600383015460069093015460ff909416939192909185565b6040516101ab959493929190613e66565b61018a6103c4366004613b1d565b610e4b565b6102b2610e9d565b6004546001600160a01b0316610221565b6102216103f0366004613b1d565b610ead565b61018a610403366004613c88565b610f7a565b600061041333610fdd565b116104395760405162461bcd60e51b815260040161043090613e9b565b60405180910390fd5b6104568585858585600080516020614a3e83398151915233611151565b5050505050565b60008281526006602090815260408083206001600160a01b038516845260020190915281205415155b90505b92915050565b600061049a33610fdd565b116104b75760405162461bcd60e51b815260040161043090613e9b565b61054c8989898989808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506104fd92508a91508b9050614065565b87878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061053a9250610b73915050565b6004546001600160a01b0316336111bb565b50505050505050505050565b3330146105775760405162461bcd60e51b815260040161043090614072565b6000816001600160a01b03163b116105a15760405162461bcd60e51b8152600401610430906140b9565b6105aa816112f0565b50565b6104568585858585600080516020614a3e833981519152611345565b600082815260016020908152604080832084845290915281206004810154600582015460609384939291906105fe8284614113565b9050806001600160401b0381111561061857610618613ee2565b604051908082528060200260200182016040528015610641578160200160208202803683370190505b509550806001600160401b0381111561065c5761065c613ee2565b6040519080825280602002602001820160405280156106a757816020015b604080516060810182526000808252602080830182905292820152825260001990920191018161067a5790505b50945060005b838110156107aa5760008782815181106106c9576106c9614126565b602002602001019060018111156106e2576106e2613b5c565b908160018111156106f5576106f5613b5c565b90525060008981526001602090815260408083208b84529091528120600487018054600790920192918490811061072e5761072e614126565b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815460ff1681526001820154938101939093526002015490820152865187908390811061078c5761078c614126565b602002602001018190525080806107a29061413c565b9150506106ad565b5060005b828110156108bb576001876107c38684614113565b815181106107d3576107d3614126565b602002602001019060018111156107ec576107ec613b5c565b908160018111156107ff576107ff613b5c565b90525060008981526001602090815260408083208b84529091528120600587018054600790920192918490811061083857610838614126565b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815460ff16815260018201549381019390935260020154908201528661088d8684614113565b8151811061089d5761089d614126565b602002602001018190525080806108b39061413c565b9150506107ae565b50505050509250929050565b6000806000836001600160a01b03166040516108ed90635c60da1b60e01b815260040190565b600060405180830381855afa9150503d8060008114610928576040519150601f19603f3d011682016040523d82523d6000602084013e61092d565b606091505b50915091508161099d5760405162461bcd60e51b815260206004820152603560248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c2060696d706044820152741b195b595b9d185d1a5bdb8a0a580819985a5b1959605a1b6064820152608401610430565b808060200190518101906109b19190614155565b949350505050565b600083815260016020818152604080842086855282528084206001600160a01b03861685526007019091528220015415156109b1565b333014610a0e5760405162461bcd60e51b815260040161043090614072565b6105aa81600255565b6104568585858585600080516020614a3e833981519152610a406003546001600160a01b031690565b6004546001600160a01b03166113cc565b6060816001600160401b03811115610a6b57610a6b613ee2565b604051908082528060200260200182016040528015610ab657816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181610a895790505b50905060005b82811015610b6b57600085815260086020526040812090858584818110610ae557610ae5614126565b9050602002016020810190610afa9190613b1d565b6001600160a01b0316815260208082019290925260409081016000208151606081018352815460ff16815260018201549381019390935260020154908201528251839083908110610b4d57610b4d614126565b60200260200101819052508080610b639061413c565b915050610abc565b509392505050565b6003546001600160a01b031690565b610ba68484848489610b92611480565b600080516020614a3e8339815191526115ec565b60008581526006602052604090206001815460ff166003811115610bcc57610bcc613b5c565b03610c1e5760058690556040517f1599b04a1104d19ef534dc177f3de0164ef5e4b99fad7485eda134600fca5f0290610c0a90889088908890614172565b60405180910390a1805460ff191660021781555b505050505050565b333014610c455760405162461bcd60e51b815260040161043090614072565b604080516001600160a01b0383811660248084019190915283518084039091018152604490920183526020820180516001600160e01b03166308f2839760e41b1790529151600092851691610c99916141ee565b6000604051808303816000865af19150503d8060008114610cd6576040519150601f19603f3d011682016040523d82523d6000602084013e610cdb565b606091505b5050905080610d525760405162461bcd60e51b815260206004820152603960248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c206063686160448201527f6e676541646d696e28616464726573732960206661696c6564000000000000006064820152608401610430565b505050565b610d618282611924565b5050565b6000610d7033610fdd565b11610d8d5760405162461bcd60e51b815260040161043090613e9b565b610e3e8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c918291850190849080828437600092019190915250610e0392508a91508b9050614065565b87878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525033925061194c915050565b5050505050505050505050565b333014610e6a5760405162461bcd60e51b815260040161043090614072565b6000816001600160a01b03163b11610e945760405162461bcd60e51b8152600401610430906140b9565b6105aa81611a64565b6000610ea860025490565b905090565b6000806000836001600160a01b0316604051610ed3906303e1469160e61b815260040190565b600060405180830381855afa9150503d8060008114610f0e576040519150601f19603f3d011682016040523d82523d6000602084013e610f13565b606091505b50915091508161099d5760405162461bcd60e51b815260206004820152602c60248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c206061646d60448201526b1a5b8a0a580819985a5b195960a21b6064820152608401610430565b6000610f8533610fdd565b11610fa25760405162461bcd60e51b815260040161043090613e9b565b610c1e8585858585600080516020614a3e833981519152610fcb6003546001600160a01b031690565b6004546001600160a01b031633611ab2565b6000806000610ff46003546001600160a01b031690565b604080516001600160a01b03878116602480840191909152835180840382018152604490930184526020830180516001600160e01b0316631af0725f60e31b1790529251931692634bb5274a9261104c929101614236565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161108591906141ee565b600060405180830381855afa9150503d80600081146110c0576040519150601f19603f3d011682016040523d82523d6000602084013e6110c5565b606091505b50915091508161113d5760405162461bcd60e51b815260206004820152603f60248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c206067657460448201527f476f7665726e6f7257656967687428616464726573732960206661696c6564006064820152608401610430565b808060200190518101906109b19190614249565b61116361115d8861434c565b82611b15565b5060006111776111728961434c565b611bfd565b90506111b16111858961434c565b8888888861119d89611198896000611d9c565b611df2565b6111ac8a6111988a6001611d9c565b611e19565b5050505050505050565b6040805160c08101909152600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554909182918190611203906001614113565b81526020018c81526020018b8b808060200260200160405190810160405280939291908181526020018383602002808284376000920182905250938552505050602082018b9052604082018a90526060909101889052909150611267828787612172565b905061127e6002548261233890919063ffffffff16565b600061128982611bfd565b90506112976000828f612434565b935080847f771d78ae9e5fca95a532fb0971d575d0ce9b59d14823c063e08740137e0e0eca846112c687612562565b878a6040516112d89493929190614568565b60405180910390a35050509998505050505050505050565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5cbd8a0bb00196365d5eb3457c6734e7f06666c3c78e5469b4c9deec7edae048906020015b60405180910390a150565b60006113536111728861434c565b6020808901356000908152600180835260408083208c358452909352919020015490915081146113955760405162461bcd60e51b81526004016104309061464f565b6113c36113a18861434c565b878787876113b488611198896000611d9c565b6111ac896111988a6001611d9c565b50505050505050565b60006113e383836113dc8c61470f565b9190612172565b905060006113f86113f38b61470f565b612562565b905061140382611bfd565b600080805260016020818152855183527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb499052604090912001541461145a5760405162461bcd60e51b81526004016104309061464f565b61054c828a8a8a8a6114718b611198896000611d9c565b6111ac8c6111988a6001611d9c565b60008060006114976003546001600160a01b031690565b6040805160048152602480820183526020820180516001600160e01b0316637de5dedd60e01b17905291516001600160a01b039390931692634bb5274a926114e0929101614236565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161151991906141ee565b600060405180830381855afa9150503d8060008114611554576040519150601f19603f3d011682016040523d82523d6000602084013e611559565b606091505b5091509150816115d15760405162461bcd60e51b815260206004820152603860248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c20606d696e60448201527f696d756d566f7465576569676874282960206661696c656400000000000000006064820152608401610430565b808060200190518101906115e59190614249565b9250505090565b6005548310156116575760405162461bcd60e51b815260206004820152603060248201527f424f73476f7665726e616e636550726f706f73616c3a20717565727920666f7260448201526f081bdd5d19185d1959081c195c9a5bd960821b6064820152608401610430565b851580159061166557508315155b6116c55760405162461bcd60e51b815260206004820152602b60248201527f424f73476f7665726e616e636550726f706f73616c3a20696e76616c6964206160448201526a0e4e4c2f240d8cadccee8d60ab1b6064820152608401610430565b60408051606081018252600080825260208201819052918101919091526000806000611724878c8c808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506126bc92505050565b905060006117328683611df2565b6000898152600660205260408120919250805b8b8110156118b4578c8c8281811061175f5761175f614126565b90506060020180360381019061177591906147d9565b975061178f8489600001518a602001518b6040015161271d565b9650866001600160a01b0316866001600160a01b0316106117fe5760405162461bcd60e51b8152602060048201526024808201527f424f73476f7665726e616e636550726f706f73616c3a20696e76616c6964206f604482015263393232b960e11b6064820152608401610430565b869550600061180c88612745565b905080156118a1576001600160a01b03881660008181526007602090815260408083204390558f835260088252808320938352928152908290208b51815460ff191660ff909116178155908b0151600180830191909155918b015160029091015592508261187d858a848f8b6128b0565b600381111561188e5761188e613b5c565b036118a1575050505050505050506113c3565b50806118ac8161413c565b915050611745565b50806119145760405162461bcd60e51b815260206004820152602960248201527f424f73476f7665726e616e636550726f706f73616c3a20696e76616c6964207360448201526869676e61747572657360b81b6064820152608401610430565b5050505050505050505050505050565b60008281526001602090815260408083208484529091529020611946816129ac565b50505050565b60008760000361199e5760405162461bcd60e51b815260206004820181905260248201527f436f7265476f7665726e616e63653a20696e76616c696420636861696e2069646044820152606401610430565b6040805160e08101825260008a815260208190529182205481906119c3906001614113565b81526020018a8152602001898152602001888152602001878152602001868152602001858152509050611a016002548261233890919063ffffffff16565b6000611a0c82611bfd565b9050611a198a828b612434565b925080838b7fa57d40f1496988cf60ab7c9d5ba4ff83647f67d3898d441a3aaf21b651678fd98588604051611a4f929190614840565b60405180910390a45050979650505050505050565b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527ffd6f5f93d69a07c593a09be0b208bff13ab4ffd6017df3b33433d63bdc59b4d79060200161133a565b611aba61386f565b611ace611ac68b61470f565b858585612b3c565b5090506000611adf6113f38c61470f565b9050611b07828b8b8b8b611af88c611198896000611d9c565b6111ac8d6111988a6001611d9c565b509998505050505050505050565b6020820151600090808203611b6c5760405162461bcd60e51b815260206004820181905260248201527f436f7265476f7665726e616e63653a20696e76616c696420636861696e2069646044820152606401610430565b600254611b7a908590612338565b6000611b8585611bfd565b9050611b9682828760400151612434565b85519093508314611bb95760405162461bcd60e51b81526004016104309061486a565b8083837fa57d40f1496988cf60ab7c9d5ba4ff83647f67d3898d441a3aaf21b651678fd98888604051611bed929190614840565b60405180910390a4505092915050565b6000806000806000808660800151905060008760600151905060008860a00151516001600160401b03811115611c3557611c35613ee2565b604051908082528060200260200182016040528015611c5e578160200160208202803683370190505b5060c08a015190915060005b8251811015611cc7578a60a001518181518110611c8957611c89614126565b602002602001015180519060200120838281518110611caa57611caa614126565b602090810291909101015280611cbf8161413c565b915050611c6a565b506020835102602084012097506020845102602085012096506020825102602083012095506020815102602082012094507fd051578048e6ff0bbc9fca3b65a42088dbde10f36ca841de566711087ad9b08a60001b8a600001518b602001518c604001518b8b8b8b604051602001611d77989796959493929190978852602088019690965260408701949094526060860192909252608085015260a084015260c083015260e08201526101000190565b6040516020818303038152906040528051906020012098505050505050505050919050565b604051600090611dd4907fd900570327c4c0df8dd6bdd522b7da7e39145dd049d2fd4602276adcd511e3c290859085906020016148b0565b60405160208183030381529060405280519060200120905092915050565b60405161190160f01b60208201526022810183905260428101829052600090606201611dd4565b8415801590611e2757508483145b611e845760405162461bcd60e51b815260206004820152602860248201527f476f7665726e616e636550726f706f73616c3a20696e76616c696420617272616044820152670f240d8cadccee8d60c31b6064820152608401610430565b6000611e8e611480565b9050600081611e9b612bf9565b611ea591906148d5565b611eb0906001614113565b9050600080611ed8604080516060810182526000808252602082018190529181019190915290565b6000805b89811015612106578a8a82818110611ef657611ef6614126565b905060600201803603810190611f0c91906147d9565b925060008d8d83818110611f2257611f22614126565b9050602002016020810190611f3791906148e8565b6001811115611f4857611f48613b5c565b03611f6c57611f658984600001518560200151866040015161271d565b9350612027565b60018d8d83818110611f8057611f80614126565b9050602002016020810190611f9591906148e8565b6001811115611fa657611fa6613b5c565b03611fc357611f658884600001518560200151866040015161271d565b60405162461bcd60e51b815260206004820152603360248201527f476f7665726e616e636550726f706f73616c3a20717565727920666f7220756e604482015272737570706f7274656420766f7465207479706560681b6064820152608401610430565b836001600160a01b0316856001600160a01b0316106120925760405162461bcd60e51b815260206004820152602160248201527f476f7665726e616e636550726f706f73616c3a20696e76616c6964206f7264656044820152603960f91b6064820152608401610430565b83945060006120a085610fdd565b905080156120f357600192506120e18f8f8f858181106120c2576120c2614126565b90506020020160208101906120d791906148e8565b8a8a898987612d40565b156120f35750505050505050506113c3565b50806120fe8161413c565b915050611edc565b50806121635760405162461bcd60e51b815260206004820152602660248201527f476f7665726e616e636550726f706f73616c3a20696e76616c6964207369676e60448201526561747572657360d01b6064820152608401610430565b50505050505050505050505050565b61217a61386f565b83518152602080850151604080840191909152600091830191909152840151516001600160401b038111156121b1576121b1613ee2565b6040519080825280602002602001820160405280156121da578160200160208202803683370190505b5060608083019190915284015160808083019190915284015160a08083019190915284015160c082015260005b846040015151811015610b6b5760018560400151828151811061222c5761222c614126565b6020026020010151600181111561224557612245613b5c565b0361228657828260600151828151811061226157612261614126565b60200260200101906001600160a01b031690816001600160a01b031681525050612326565b60008560400151828151811061229e5761229e614126565b602002602001015160018111156122b7576122b7613b5c565b036122d357838260600151828151811061226157612261614126565b60405162461bcd60e51b815260206004820152602260248201527f476c6f62616c50726f706f73616c3a20756e737570706f727465642074617267604482015261195d60f21b6064820152608401610430565b806123308161413c565b915050612207565b60008260600151511180156123565750816080015151826060015151145b801561236b57508160a0015151826060015151145b801561238057508160c0015151826060015151145b6123cc5760405162461bcd60e51b815260206004820152601e60248201527f50726f706f73616c3a20696e76616c6964206172726179206c656e67746800006044820152606401610430565b6123d68142614113565b82604001511115610d615760405162461bcd60e51b815260206004820152602260248201527f50726f706f73616c3a20696e76616c6964206578706972792074696d6573746160448201526106d760f41b6064820152608401610430565b6000838152602081905260408120549081900361246557506000838152602081905260409020600190819055612535565b6000848152600160209081526040808320848452909152812090612488826129ac565b905080612532576000825460ff1660038111156124a7576124a7613b5c565b0361250e5760405162461bcd60e51b815260206004820152603160248201527f436f7265476f7665726e616e63653a2063757272656e742070726f706f73616c604482015270081a5cc81b9bdd0818dbdb5c1b195d1959607a1b6064820152608401610430565b6000868152602081905260408120805490919061252a9061413c565b918290555092505b50505b60009384526001602081815260408087208488529091529094209384019290925560069092019190915590565b6000806000806000808660600151905060008760400151905060008860800151516001600160401b0381111561259a5761259a613ee2565b6040519080825280602002602001820160405280156125c3578160200160208202803683370190505b5060a08a015190915060005b825181101561262c578a6080015181815181106125ee576125ee614126565b60200260200101518051906020012083828151811061260f5761260f614126565b6020908102919091010152806126248161413c565b9150506125cf565b5082516020908102848201208551820286830120845183028584012084518402858501208e518f860151604080517f1463f426c05aff2c1a7a0957a71c9898bc8b47142540538e79ee25ee911413509881019890985287019190915260608601526080850184905260a0850183905260c0850182905260e08501819052929b509099509750955061010001611d77565b8051602090810291810191909120604080517feea5e3908ac28cbdbbce8853e49444c558a0a03597e98ef19e6ff86162ed9ae38185015280820194909452606080850192909252805180850390920182526080909301909252815191012090565b600080600061272e87878787613107565b9150915061273b816131f4565b5095945050505050565b600080600061275c6003546001600160a01b031690565b604080516001600160a01b03878116602480840191909152835180840382018152604490930184526020830180516001600160e01b0316635624191160e01b1790529251931692634bb5274a926127b4929101614236565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516127ed91906141ee565b600060405180830381855afa9150503d8060008114612828576040519150601f19603f3d011682016040523d82523d6000602084013e61282d565b606091505b50915091508161113d5760405162461bcd60e51b815260206004820152604260248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c206067657460448201527f427269646765566f74657257656967687428616464726573732960206661696c606482015261195960f21b608482015260a401610430565b6001600160a01b03841660009081526002860160205260408120541561291a576128e4856001600160a01b031660146133aa565b6040516020016128f49190614905565b60408051601f198184030181529082905262461bcd60e51b825261043091600401614236565b6001600160a01b0385166000908152600287016020908152604080832085905584835260038901909152812080548691908390612958908490614113565b925050819055905083811015801561298557506000875460ff16600381111561298357612983613b5c565b145b1561299d57865460ff19166001908117885587018390555b5050935460ff16949350505050565b600080825460ff1660038111156129c5576129c5613b5c565b1480156129d6575042826006015411155b90508015612b375760018201546040517f58f98006a7f2f253f8ae8f8b7cec9008ca05359633561cd7c22f3005682d4a5590600090a260005b6004830154811015612a7f57826007016000846004018381548110612a3657612a36614126565b60009182526020808320909101546001600160a01b031683528201929092526040018120805460ff19168155600181018290556002015580612a778161413c565b915050612a0f565b5060005b6005830154811015612af357826007016000846005018381548110612aaa57612aaa614126565b60009182526020808320909101546001600160a01b031683528201929092526040018120805460ff19168155600181018290556002015580612aeb8161413c565b915050612a83565b50815460ff191682556000600183018190556002830181905560038301819055612b219060048401906138ac565b612b2f6005830160006138ac565b600060068301555b919050565b612b4461386f565b6000612b51868686612172565b9150612b686002548361233890919063ffffffff16565b6000612b7383611bfd565b9050612b856000828960200151612434565b83519092508214612ba85760405162461bcd60e51b81526004016104309061486a565b80827f771d78ae9e5fca95a532fb0971d575d0ce9b59d14823c063e08740137e0e0eca85612bd58b612562565b8b89604051612be79493929190614568565b60405180910390a35094509492505050565b6000806000612c106003546001600160a01b031690565b6040805160048152602480820183526020820180516001600160e01b031663926323d560e01b17905291516001600160a01b039390931692634bb5274a92612c59929101614236565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051612c9291906141ee565b600060405180830381855afa9150503d8060008114612ccd576040519150601f19603f3d011682016040523d82523d6000602084013e612cd2565b606091505b5091509150816115d15760405162461bcd60e51b815260206004820152603360248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c2060746f74604482015272185b15d95a59da1d1cca0a580819985a5b1959606a1b6064820152608401610430565b60208088015188516000828152600184526040808220838352909452928320612d68816129ac565b15612d7957600193505050506130fc565b6020808c015160009081529081905260409020548214612df45760405162461bcd60e51b815260206004820152603060248201527f436f7265476f7665726e616e63653a20717565727920666f7220696e76616c6960448201526f642070726f706f73616c206e6f6e636560801b6064820152608401610430565b6000815460ff166003811115612e0c57612e0c613b5c565b14612e675760405162461bcd60e51b815260206004820152602560248201527f436f7265476f7665726e616e63653a2074686520766f74652069732066696e616044820152641b1a5e995960da1b6064820152608401610430565b6001600160a01b038716600090815260078201602052604090206001015415612eae57612e9e876001600160a01b031660146133aa565b6040516020016128f49190614959565b6001600160a01b03871660008181526007830160209081526040918290208951815460ff191660ff909116178155908901516001808301919091558983015160029092019190915583015490517f1203f9e81c814a35f5f4cc24087b2a24c6fb7986a9f1406b68a9484882c93a2390612f2a908e908a906149a9565b60405180910390a3600080808c6001811115612f4857612f48613b5c565b03612f9d576004830180546001810182556000918252602082200180546001600160a01b0319166001600160a01b038c16179055600384018054899290612f90908490614113565b925050819055915061305c565b60018c6001811115612fb157612fb1613b5c565b03613006576005830180546001810182556000918252602082200180546001600160a01b0319166001600160a01b038c16179055600284018054899290612ff9908490614113565b925050819055905061305c565b60405162461bcd60e51b815260206004820152602560248201527f436f7265476f7665726e616e63653a20756e737570706f7274656420766f7465604482015264207479706560d81b6064820152608401610430565b8a82106130b057825460ff19166001908117845580840154604051919750907f5c819725ea53655a3b898f3df59b66489761935454e9212ca1e5ebd759953d0b90600090a26130ab838e613545565b6130f6565b8981106130f657825460ff19166003178355600180840154604051919750907f55295d4ce992922fa2e5ffbf3a3dcdb367de0a15e125ace083456017fd22060f90600090a25b50505050505b979650505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561313e57506000905060036131eb565b8460ff16601b1415801561315657508460ff16601c14155b1561316757506000905060046131eb565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156131bb573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166131e4576000600192509250506131eb565b9150600090505b94509492505050565b600081600481111561320857613208613b5c565b036132105750565b600181600481111561322457613224613b5c565b036132715760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610430565b600281600481111561328557613285613b5c565b036132d25760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610430565b60038160048111156132e6576132e6613b5c565b0361333e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610430565b600481600481111561335257613352613b5c565b036105aa5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610430565b606060006133b98360026149c0565b6133c4906002614113565b6001600160401b038111156133db576133db613ee2565b6040519080825280601f01601f191660200182016040528015613405576020820181803683370190505b509050600360fc1b8160008151811061342057613420614126565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061344f5761344f614126565b60200101906001600160f81b031916908160001a90535060006134738460026149c0565b61347e906001614113565b90505b60018111156134f6576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106134b2576134b2614126565b1a60f81b8282815181106134c8576134c8614126565b60200101906001600160f81b031916908160001a90535060049490941c936134ef816149d7565b9050613481565b5083156104865760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610430565b61354e816135b2565b15610d6157815460ff1916600217825560008061356a836135cc565b9150915083600101547fe134987599ae266ec90edeff1b26125b287dbb57b10822649432d1bb26537fba83836040516135a49291906149ee565b60405180910390a250505050565b600081602001516000148061048957505060200151461490565b6060806135d8836135b2565b6136305760405162461bcd60e51b815260206004820152602360248201527f50726f706f73616c3a20717565727920666f7220696e76616c696420636861696044820152621b925960ea1b6064820152608401610430565b8260600151516001600160401b0381111561364d5761364d613ee2565b604051908082528060200260200182016040528015613676578160200160208202803683370190505b5091508260600151516001600160401b0381111561369657613696613ee2565b6040519080825280602002602001820160405280156136c957816020015b60608152602001906001900390816136b45790505b50905060005b836060015151811015613869578360c0015181815181106136f2576136f2614126565b60200260200101515a116137485760405162461bcd60e51b815260206004820152601a60248201527f50726f706f73616c3a20696e73756666696369656e74206761730000000000006044820152606401610430565b8360600151818151811061375e5761375e614126565b60200260200101516001600160a01b03168460800151828151811061378557613785614126565b60200260200101518560c0015183815181106137a3576137a3614126565b6020026020010151908660a0015184815181106137c2576137c2614126565b60200260200101516040516137d791906141ee565b600060405180830381858888f193505050503d8060008114613815576040519150601f19603f3d011682016040523d82523d6000602084013e61381a565b606091505b5084838151811061382d5761382d614126565b6020026020010184848151811061384657613846614126565b602090810291909101019190915290151590526138628161413c565b90506136cf565b50915091565b6040518060e00160405280600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b50805460008255906000526020600020908101906105aa91905b808211156138da57600081556001016138c6565b5090565b60008083601f8401126138f057600080fd5b5081356001600160401b0381111561390757600080fd5b6020830191508360208260051b850101111561392257600080fd5b9250929050565b60008083601f84011261393b57600080fd5b5081356001600160401b0381111561395257600080fd5b60208301915083602060608302850101111561392257600080fd5b60008060008060006060868803121561398557600080fd5b85356001600160401b038082111561399c57600080fd5b9087019060e0828a0312156139b057600080fd5b909550602087013590808211156139c657600080fd5b6139d289838a016138de565b909650945060408801359150808211156139eb57600080fd5b506139f888828901613929565b969995985093965092949392505050565b6001600160a01b03811681146105aa57600080fd5b60008060408385031215613a3157600080fd5b823591506020830135613a4381613a09565b809150509250929050565b600080600080600080600080600060a08a8c031215613a6c57600080fd5b8935985060208a01356001600160401b0380821115613a8a57600080fd5b613a968d838e016138de565b909a50985060408c0135915080821115613aaf57600080fd5b613abb8d838e016138de565b909850965060608c0135915080821115613ad457600080fd5b613ae08d838e016138de565b909650945060808c0135915080821115613af957600080fd5b50613b068c828d016138de565b915080935050809150509295985092959850929598565b600060208284031215613b2f57600080fd5b813561048681613a09565b60008060408385031215613b4d57600080fd5b50508035926020909101359150565b634e487b7160e01b600052602160045260246000fd5b600281106105aa576105aa613b5c565b600081518084526020808501945080840160005b83811015613bcb578151805160ff16885283810151848901526040908101519088015260609096019590820190600101613b96565b509495945050505050565b604080825283519082018190526000906020906060840190828701845b82811015613c18578151613c0681613b72565b84529284019290840190600101613bf3565b50505083810382850152613c2c8186613b82565b9695505050505050565b600080600060608486031215613c4b57600080fd5b83359250602084013591506040840135613c6481613a09565b809150509250925092565b600060208284031215613c8157600080fd5b5035919050565b600080600080600060608688031215613ca057600080fd5b85356001600160401b0380821115613cb757600080fd5b9087019060c0828a0312156139b057600080fd5b600080600060408486031215613ce057600080fd5b8335925060208401356001600160401b03811115613cfd57600080fd5b613d09868287016138de565b9497909650939450505050565b6020815260006104866020830184613b82565b600080600080600060608688031215613d4157600080fd5b8535945060208601356001600160401b03808211156139c657600080fd5b60008060408385031215613d7257600080fd5b8235613d7d81613a09565b91506020830135613a4381613a09565b60008060008060008060008060008060c08b8d031215613dac57600080fd5b8a35995060208b0135985060408b01356001600160401b0380821115613dd157600080fd5b613ddd8e838f016138de565b909a50985060608d0135915080821115613df657600080fd5b613e028e838f016138de565b909850965060808d0135915080821115613e1b57600080fd5b613e278e838f016138de565b909650945060a08d0135915080821115613e4057600080fd5b50613e4d8d828e016138de565b915080935050809150509295989b9194979a5092959850565b60a0810160048710613e7a57613e7a613b5c565b95815260208101949094526040840192909252606083015260809091015290565b60208082526027908201527f476f7665726e616e636541646d696e3a2073656e646572206973206e6f74206760408201526637bb32b93737b960c91b606082015260800190565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b0381118282101715613f1a57613f1a613ee2565b60405290565b60405160c081016001600160401b0381118282101715613f1a57613f1a613ee2565b604051601f8201601f191681016001600160401b0381118282101715613f6a57613f6a613ee2565b604052919050565b60006001600160401b03821115613f8b57613f8b613ee2565b5060051b60200190565b6000613fa8613fa384613f72565b613f42565b8381529050602080820190600585901b840186811115613fc757600080fd5b845b8181101561405a5780356001600160401b0380821115613fe95760008081fd5b8188019150601f8a81840112613fff5760008081fd5b82358281111561401157614011613ee2565b614022818301601f19168801613f42565b92508083528b8782860101111561403b57600091508182fd5b8087850188850137600090830187015250855250928201928201613fc9565b505050509392505050565b6000610486368484613f95565b60208082526027908201527f476f7665726e616e636541646d696e3a206f6e6c7920616c6c6f7765642073656040820152661b198b58d85b1b60ca1b606082015260800190565b60208082526024908201527f476f7665726e616e636541646d696e3a2073657420746f206e6f6e2d636f6e746040820152631c9858dd60e21b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b80820180821115610489576104896140fd565b634e487b7160e01b600052603260045260246000fd5b60006001820161414e5761414e6140fd565b5060010190565b60006020828403121561416757600080fd5b815161048681613a09565b83815260406020808301829052908201839052600090849060608401835b868110156141be5783356141a381613a09565b6001600160a01b031682529282019290820190600101614190565b50979650505050505050565b60005b838110156141e55781810151838201526020016141cd565b50506000910152565b600082516142008184602087016141ca565b9190910192915050565b600081518084526142228160208601602086016141ca565b601f01601f19169290920160200192915050565b602081526000610486602083018461420a565b60006020828403121561425b57600080fd5b5051919050565b600082601f83011261427357600080fd5b81356020614283613fa383613f72565b82815260059290921b840181019181810190868411156142a257600080fd5b8286015b848110156142c65780356142b981613a09565b83529183019183016142a6565b509695505050505050565b600082601f8301126142e257600080fd5b813560206142f2613fa383613f72565b82815260059290921b8401810191818101908684111561431157600080fd5b8286015b848110156142c65780358352918301918301614315565b600082601f83011261433d57600080fd5b61048683833560208501613f95565b600060e0823603121561435e57600080fd5b614366613ef8565b82358152602083013560208201526040830135604082015260608301356001600160401b038082111561439857600080fd5b6143a436838701614262565b606084015260808501359150808211156143bd57600080fd5b6143c9368387016142d1565b608084015260a08501359150808211156143e257600080fd5b6143ee3683870161432c565b60a084015260c085013591508082111561440757600080fd5b50614414368286016142d1565b60c08301525092915050565b600081518084526020808501945080840160005b83811015613bcb57815187529582019590820190600101614434565b600081518084526020808501808196508360051b8101915082860160005b8581101561449857828403895261448684835161420a565b9885019893509084019060010161446e565b5091979650505050505050565b600060e08301825184526020808401518186015260408401516040860152606084015160e06060870152828151808552610100880191508383019450600092505b8083101561450f5784516001600160a01b031682529383019360019290920191908301906144e6565b506080860151935086810360808801526145298185614420565b935050505060a083015184820360a08601526145458282614450565b91505060c083015184820360c086015261455f8282614420565b95945050505050565b60808152600061457b60808301876144a5565b60208681850152838203604085015260c08201865183528187015182840152604087015160c0604085015281815180845260e0860191508483019350600092505b808310156145e55783516145cf81613b72565b82529284019260019290920191908401906145bc565b506060890151935084810360608601526145ff8185614420565b93505050506080860151828203608084015261461b8282614450565b91505060a086015182820360a08401526146358282614420565b935050505061455f60608301846001600160a01b03169052565b6020808252602f908201527f476f7665726e616e636541646d696e3a206361737420766f746520666f72206960408201526e1b9d985b1a59081c1c9bdc1bdcd85b608a1b606082015260800190565b600281106105aa57600080fd5b600082601f8301126146bc57600080fd5b813560206146cc613fa383613f72565b82815260059290921b840181019181810190868411156146eb57600080fd5b8286015b848110156142c65780356147028161469e565b83529183019183016146ef565b600060c0823603121561472157600080fd5b614729613f20565b823581526020830135602082015260408301356001600160401b038082111561475157600080fd5b61475d368387016146ab565b6040840152606085013591508082111561477657600080fd5b614782368387016142d1565b6060840152608085013591508082111561479b57600080fd5b6147a73683870161432c565b608084015260a08501359150808211156147c057600080fd5b506147cd368286016142d1565b60a08301525092915050565b6000606082840312156147eb57600080fd5b604051606081018181106001600160401b038211171561480d5761480d613ee2565b604052823560ff8116811461482157600080fd5b8152602083810135908201526040928301359281019290925250919050565b60408152600061485360408301856144a5565b905060018060a01b03831660208301529392505050565b60208082526026908201527f436f7265476f7665726e616e63653a20696e76616c69642070726f706f73616c604082015265206e6f6e636560d01b606082015260800190565b83815260208101839052606081016148c783613b72565b826040830152949350505050565b81810381811115610489576104896140fd565b6000602082840312156148fa57600080fd5b81356104868161469e565b73024b9b7b630ba32b223b7bb32b93730b731b29d160651b8152600082516149348160148501602087016141ca565b6d08185b1c9958591e481d9bdd195960921b6014939091019283015250602201919050565b6f021b7b932a3b7bb32b93730b731b29d160851b8152600082516149848160108501602087016141ca565b6d08185b1c9958591e481d9bdd195960921b6010939091019283015250601e01919050565b604081016149b684613b72565b9281526020015290565b8082028115828204841417610489576104896140fd565b6000816149e6576149e66140fd565b506000190190565b604080825283519082018190526000906020906060840190828701845b82811015614a29578151151584529284019290840190600101614a0b565b50505083810382850152613c2c818661445056fef8704f8860d9e985bf6c52ec4738bd10fe31487599b36c0944f746ea09dc256ba26469706673582212206d28c066dbd7031ca119cf1d6a454f01cf9481a218158d2145b1f9fdc5e70f3e64736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101725760003560e01c80633644e515116100de578063a1819f9a11610097578063bc96180b11610071578063bc96180b146103c9578063cd596583146103d1578063f3b7dead146103e2578063fb4f6371146103f557600080fd5b8063a1819f9a14610348578063b384abef1461035b578063b5e337de146103b657600080fd5b80633644e515146102c05780635511cde1146102d557806356e237e8146102e65780637eff275e146102f9578063988ef53c1461030c5780639a7d33821461033557600080fd5b8063204e1c7a11610130578063204e1c7a1461020e5780632c5e6520146102395780632e96a6fb1461024c5780632faf925d1461025f578063332635be1461027257806334d5f37b1461029257600080fd5b80624054b814610177578063055c68891461018c57806309fcd8c7146101b45780630b26cf66146101c75780630b881830146101da5780631c905e39146101ed575b600080fd5b61018a61018536600461396d565b610408565b005b61019f61019a366004613a1e565b61045d565b60405190151581526020015b60405180910390f35b61018a6101c2366004613a4e565b61048f565b61018a6101d5366004613b1d565b610558565b61018a6101e836600461396d565b6105ad565b6102006101fb366004613b3a565b6105c9565b6040516101ab929190613bd6565b61022161021c366004613b1d565b6108c7565b6040516001600160a01b0390911681526020016101ab565b61019f610247366004613c36565b6109b9565b61018a61025a366004613c6f565b6109ef565b61018a61026d366004613c88565b610a17565b610285610280366004613ccb565b610a51565b6040516101ab9190613d16565b6102b26102a0366004613c6f565b60006020819052908152604090205481565b6040519081526020016101ab565b6102b2600080516020614a3e83398151915281565b6003546001600160a01b0316610221565b61018a6102f4366004613d29565b610b82565b61018a610307366004613d5f565b610c26565b6102b261031a366004613b1d565b6001600160a01b031660009081526007602052604090205490565b61018a610343366004613b3a565b610d57565b61018a610356366004613d8d565b610d65565b6103a5610369366004613b3a565b600160208181526000938452604080852090915291835291208054918101546002820154600383015460069093015460ff909416939192909185565b6040516101ab959493929190613e66565b61018a6103c4366004613b1d565b610e4b565b6102b2610e9d565b6004546001600160a01b0316610221565b6102216103f0366004613b1d565b610ead565b61018a610403366004613c88565b610f7a565b600061041333610fdd565b116104395760405162461bcd60e51b815260040161043090613e9b565b60405180910390fd5b6104568585858585600080516020614a3e83398151915233611151565b5050505050565b60008281526006602090815260408083206001600160a01b038516845260020190915281205415155b90505b92915050565b600061049a33610fdd565b116104b75760405162461bcd60e51b815260040161043090613e9b565b61054c8989898989808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506104fd92508a91508b9050614065565b87878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061053a9250610b73915050565b6004546001600160a01b0316336111bb565b50505050505050505050565b3330146105775760405162461bcd60e51b815260040161043090614072565b6000816001600160a01b03163b116105a15760405162461bcd60e51b8152600401610430906140b9565b6105aa816112f0565b50565b6104568585858585600080516020614a3e833981519152611345565b600082815260016020908152604080832084845290915281206004810154600582015460609384939291906105fe8284614113565b9050806001600160401b0381111561061857610618613ee2565b604051908082528060200260200182016040528015610641578160200160208202803683370190505b509550806001600160401b0381111561065c5761065c613ee2565b6040519080825280602002602001820160405280156106a757816020015b604080516060810182526000808252602080830182905292820152825260001990920191018161067a5790505b50945060005b838110156107aa5760008782815181106106c9576106c9614126565b602002602001019060018111156106e2576106e2613b5c565b908160018111156106f5576106f5613b5c565b90525060008981526001602090815260408083208b84529091528120600487018054600790920192918490811061072e5761072e614126565b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815460ff1681526001820154938101939093526002015490820152865187908390811061078c5761078c614126565b602002602001018190525080806107a29061413c565b9150506106ad565b5060005b828110156108bb576001876107c38684614113565b815181106107d3576107d3614126565b602002602001019060018111156107ec576107ec613b5c565b908160018111156107ff576107ff613b5c565b90525060008981526001602090815260408083208b84529091528120600587018054600790920192918490811061083857610838614126565b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815460ff16815260018201549381019390935260020154908201528661088d8684614113565b8151811061089d5761089d614126565b602002602001018190525080806108b39061413c565b9150506107ae565b50505050509250929050565b6000806000836001600160a01b03166040516108ed90635c60da1b60e01b815260040190565b600060405180830381855afa9150503d8060008114610928576040519150601f19603f3d011682016040523d82523d6000602084013e61092d565b606091505b50915091508161099d5760405162461bcd60e51b815260206004820152603560248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c2060696d706044820152741b195b595b9d185d1a5bdb8a0a580819985a5b1959605a1b6064820152608401610430565b808060200190518101906109b19190614155565b949350505050565b600083815260016020818152604080842086855282528084206001600160a01b03861685526007019091528220015415156109b1565b333014610a0e5760405162461bcd60e51b815260040161043090614072565b6105aa81600255565b6104568585858585600080516020614a3e833981519152610a406003546001600160a01b031690565b6004546001600160a01b03166113cc565b6060816001600160401b03811115610a6b57610a6b613ee2565b604051908082528060200260200182016040528015610ab657816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181610a895790505b50905060005b82811015610b6b57600085815260086020526040812090858584818110610ae557610ae5614126565b9050602002016020810190610afa9190613b1d565b6001600160a01b0316815260208082019290925260409081016000208151606081018352815460ff16815260018201549381019390935260020154908201528251839083908110610b4d57610b4d614126565b60200260200101819052508080610b639061413c565b915050610abc565b509392505050565b6003546001600160a01b031690565b610ba68484848489610b92611480565b600080516020614a3e8339815191526115ec565b60008581526006602052604090206001815460ff166003811115610bcc57610bcc613b5c565b03610c1e5760058690556040517f1599b04a1104d19ef534dc177f3de0164ef5e4b99fad7485eda134600fca5f0290610c0a90889088908890614172565b60405180910390a1805460ff191660021781555b505050505050565b333014610c455760405162461bcd60e51b815260040161043090614072565b604080516001600160a01b0383811660248084019190915283518084039091018152604490920183526020820180516001600160e01b03166308f2839760e41b1790529151600092851691610c99916141ee565b6000604051808303816000865af19150503d8060008114610cd6576040519150601f19603f3d011682016040523d82523d6000602084013e610cdb565b606091505b5050905080610d525760405162461bcd60e51b815260206004820152603960248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c206063686160448201527f6e676541646d696e28616464726573732960206661696c6564000000000000006064820152608401610430565b505050565b610d618282611924565b5050565b6000610d7033610fdd565b11610d8d5760405162461bcd60e51b815260040161043090613e9b565b610e3e8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c918291850190849080828437600092019190915250610e0392508a91508b9050614065565b87878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525033925061194c915050565b5050505050505050505050565b333014610e6a5760405162461bcd60e51b815260040161043090614072565b6000816001600160a01b03163b11610e945760405162461bcd60e51b8152600401610430906140b9565b6105aa81611a64565b6000610ea860025490565b905090565b6000806000836001600160a01b0316604051610ed3906303e1469160e61b815260040190565b600060405180830381855afa9150503d8060008114610f0e576040519150601f19603f3d011682016040523d82523d6000602084013e610f13565b606091505b50915091508161099d5760405162461bcd60e51b815260206004820152602c60248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c206061646d60448201526b1a5b8a0a580819985a5b195960a21b6064820152608401610430565b6000610f8533610fdd565b11610fa25760405162461bcd60e51b815260040161043090613e9b565b610c1e8585858585600080516020614a3e833981519152610fcb6003546001600160a01b031690565b6004546001600160a01b031633611ab2565b6000806000610ff46003546001600160a01b031690565b604080516001600160a01b03878116602480840191909152835180840382018152604490930184526020830180516001600160e01b0316631af0725f60e31b1790529251931692634bb5274a9261104c929101614236565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161108591906141ee565b600060405180830381855afa9150503d80600081146110c0576040519150601f19603f3d011682016040523d82523d6000602084013e6110c5565b606091505b50915091508161113d5760405162461bcd60e51b815260206004820152603f60248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c206067657460448201527f476f7665726e6f7257656967687428616464726573732960206661696c6564006064820152608401610430565b808060200190518101906109b19190614249565b61116361115d8861434c565b82611b15565b5060006111776111728961434c565b611bfd565b90506111b16111858961434c565b8888888861119d89611198896000611d9c565b611df2565b6111ac8a6111988a6001611d9c565b611e19565b5050505050505050565b6040805160c08101909152600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554909182918190611203906001614113565b81526020018c81526020018b8b808060200260200160405190810160405280939291908181526020018383602002808284376000920182905250938552505050602082018b9052604082018a90526060909101889052909150611267828787612172565b905061127e6002548261233890919063ffffffff16565b600061128982611bfd565b90506112976000828f612434565b935080847f771d78ae9e5fca95a532fb0971d575d0ce9b59d14823c063e08740137e0e0eca846112c687612562565b878a6040516112d89493929190614568565b60405180910390a35050509998505050505050505050565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5cbd8a0bb00196365d5eb3457c6734e7f06666c3c78e5469b4c9deec7edae048906020015b60405180910390a150565b60006113536111728861434c565b6020808901356000908152600180835260408083208c358452909352919020015490915081146113955760405162461bcd60e51b81526004016104309061464f565b6113c36113a18861434c565b878787876113b488611198896000611d9c565b6111ac896111988a6001611d9c565b50505050505050565b60006113e383836113dc8c61470f565b9190612172565b905060006113f86113f38b61470f565b612562565b905061140382611bfd565b600080805260016020818152855183527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb499052604090912001541461145a5760405162461bcd60e51b81526004016104309061464f565b61054c828a8a8a8a6114718b611198896000611d9c565b6111ac8c6111988a6001611d9c565b60008060006114976003546001600160a01b031690565b6040805160048152602480820183526020820180516001600160e01b0316637de5dedd60e01b17905291516001600160a01b039390931692634bb5274a926114e0929101614236565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161151991906141ee565b600060405180830381855afa9150503d8060008114611554576040519150601f19603f3d011682016040523d82523d6000602084013e611559565b606091505b5091509150816115d15760405162461bcd60e51b815260206004820152603860248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c20606d696e60448201527f696d756d566f7465576569676874282960206661696c656400000000000000006064820152608401610430565b808060200190518101906115e59190614249565b9250505090565b6005548310156116575760405162461bcd60e51b815260206004820152603060248201527f424f73476f7665726e616e636550726f706f73616c3a20717565727920666f7260448201526f081bdd5d19185d1959081c195c9a5bd960821b6064820152608401610430565b851580159061166557508315155b6116c55760405162461bcd60e51b815260206004820152602b60248201527f424f73476f7665726e616e636550726f706f73616c3a20696e76616c6964206160448201526a0e4e4c2f240d8cadccee8d60ab1b6064820152608401610430565b60408051606081018252600080825260208201819052918101919091526000806000611724878c8c808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506126bc92505050565b905060006117328683611df2565b6000898152600660205260408120919250805b8b8110156118b4578c8c8281811061175f5761175f614126565b90506060020180360381019061177591906147d9565b975061178f8489600001518a602001518b6040015161271d565b9650866001600160a01b0316866001600160a01b0316106117fe5760405162461bcd60e51b8152602060048201526024808201527f424f73476f7665726e616e636550726f706f73616c3a20696e76616c6964206f604482015263393232b960e11b6064820152608401610430565b869550600061180c88612745565b905080156118a1576001600160a01b03881660008181526007602090815260408083204390558f835260088252808320938352928152908290208b51815460ff191660ff909116178155908b0151600180830191909155918b015160029091015592508261187d858a848f8b6128b0565b600381111561188e5761188e613b5c565b036118a1575050505050505050506113c3565b50806118ac8161413c565b915050611745565b50806119145760405162461bcd60e51b815260206004820152602960248201527f424f73476f7665726e616e636550726f706f73616c3a20696e76616c6964207360448201526869676e61747572657360b81b6064820152608401610430565b5050505050505050505050505050565b60008281526001602090815260408083208484529091529020611946816129ac565b50505050565b60008760000361199e5760405162461bcd60e51b815260206004820181905260248201527f436f7265476f7665726e616e63653a20696e76616c696420636861696e2069646044820152606401610430565b6040805160e08101825260008a815260208190529182205481906119c3906001614113565b81526020018a8152602001898152602001888152602001878152602001868152602001858152509050611a016002548261233890919063ffffffff16565b6000611a0c82611bfd565b9050611a198a828b612434565b925080838b7fa57d40f1496988cf60ab7c9d5ba4ff83647f67d3898d441a3aaf21b651678fd98588604051611a4f929190614840565b60405180910390a45050979650505050505050565b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527ffd6f5f93d69a07c593a09be0b208bff13ab4ffd6017df3b33433d63bdc59b4d79060200161133a565b611aba61386f565b611ace611ac68b61470f565b858585612b3c565b5090506000611adf6113f38c61470f565b9050611b07828b8b8b8b611af88c611198896000611d9c565b6111ac8d6111988a6001611d9c565b509998505050505050505050565b6020820151600090808203611b6c5760405162461bcd60e51b815260206004820181905260248201527f436f7265476f7665726e616e63653a20696e76616c696420636861696e2069646044820152606401610430565b600254611b7a908590612338565b6000611b8585611bfd565b9050611b9682828760400151612434565b85519093508314611bb95760405162461bcd60e51b81526004016104309061486a565b8083837fa57d40f1496988cf60ab7c9d5ba4ff83647f67d3898d441a3aaf21b651678fd98888604051611bed929190614840565b60405180910390a4505092915050565b6000806000806000808660800151905060008760600151905060008860a00151516001600160401b03811115611c3557611c35613ee2565b604051908082528060200260200182016040528015611c5e578160200160208202803683370190505b5060c08a015190915060005b8251811015611cc7578a60a001518181518110611c8957611c89614126565b602002602001015180519060200120838281518110611caa57611caa614126565b602090810291909101015280611cbf8161413c565b915050611c6a565b506020835102602084012097506020845102602085012096506020825102602083012095506020815102602082012094507fd051578048e6ff0bbc9fca3b65a42088dbde10f36ca841de566711087ad9b08a60001b8a600001518b602001518c604001518b8b8b8b604051602001611d77989796959493929190978852602088019690965260408701949094526060860192909252608085015260a084015260c083015260e08201526101000190565b6040516020818303038152906040528051906020012098505050505050505050919050565b604051600090611dd4907fd900570327c4c0df8dd6bdd522b7da7e39145dd049d2fd4602276adcd511e3c290859085906020016148b0565b60405160208183030381529060405280519060200120905092915050565b60405161190160f01b60208201526022810183905260428101829052600090606201611dd4565b8415801590611e2757508483145b611e845760405162461bcd60e51b815260206004820152602860248201527f476f7665726e616e636550726f706f73616c3a20696e76616c696420617272616044820152670f240d8cadccee8d60c31b6064820152608401610430565b6000611e8e611480565b9050600081611e9b612bf9565b611ea591906148d5565b611eb0906001614113565b9050600080611ed8604080516060810182526000808252602082018190529181019190915290565b6000805b89811015612106578a8a82818110611ef657611ef6614126565b905060600201803603810190611f0c91906147d9565b925060008d8d83818110611f2257611f22614126565b9050602002016020810190611f3791906148e8565b6001811115611f4857611f48613b5c565b03611f6c57611f658984600001518560200151866040015161271d565b9350612027565b60018d8d83818110611f8057611f80614126565b9050602002016020810190611f9591906148e8565b6001811115611fa657611fa6613b5c565b03611fc357611f658884600001518560200151866040015161271d565b60405162461bcd60e51b815260206004820152603360248201527f476f7665726e616e636550726f706f73616c3a20717565727920666f7220756e604482015272737570706f7274656420766f7465207479706560681b6064820152608401610430565b836001600160a01b0316856001600160a01b0316106120925760405162461bcd60e51b815260206004820152602160248201527f476f7665726e616e636550726f706f73616c3a20696e76616c6964206f7264656044820152603960f91b6064820152608401610430565b83945060006120a085610fdd565b905080156120f357600192506120e18f8f8f858181106120c2576120c2614126565b90506020020160208101906120d791906148e8565b8a8a898987612d40565b156120f35750505050505050506113c3565b50806120fe8161413c565b915050611edc565b50806121635760405162461bcd60e51b815260206004820152602660248201527f476f7665726e616e636550726f706f73616c3a20696e76616c6964207369676e60448201526561747572657360d01b6064820152608401610430565b50505050505050505050505050565b61217a61386f565b83518152602080850151604080840191909152600091830191909152840151516001600160401b038111156121b1576121b1613ee2565b6040519080825280602002602001820160405280156121da578160200160208202803683370190505b5060608083019190915284015160808083019190915284015160a08083019190915284015160c082015260005b846040015151811015610b6b5760018560400151828151811061222c5761222c614126565b6020026020010151600181111561224557612245613b5c565b0361228657828260600151828151811061226157612261614126565b60200260200101906001600160a01b031690816001600160a01b031681525050612326565b60008560400151828151811061229e5761229e614126565b602002602001015160018111156122b7576122b7613b5c565b036122d357838260600151828151811061226157612261614126565b60405162461bcd60e51b815260206004820152602260248201527f476c6f62616c50726f706f73616c3a20756e737570706f727465642074617267604482015261195d60f21b6064820152608401610430565b806123308161413c565b915050612207565b60008260600151511180156123565750816080015151826060015151145b801561236b57508160a0015151826060015151145b801561238057508160c0015151826060015151145b6123cc5760405162461bcd60e51b815260206004820152601e60248201527f50726f706f73616c3a20696e76616c6964206172726179206c656e67746800006044820152606401610430565b6123d68142614113565b82604001511115610d615760405162461bcd60e51b815260206004820152602260248201527f50726f706f73616c3a20696e76616c6964206578706972792074696d6573746160448201526106d760f41b6064820152608401610430565b6000838152602081905260408120549081900361246557506000838152602081905260409020600190819055612535565b6000848152600160209081526040808320848452909152812090612488826129ac565b905080612532576000825460ff1660038111156124a7576124a7613b5c565b0361250e5760405162461bcd60e51b815260206004820152603160248201527f436f7265476f7665726e616e63653a2063757272656e742070726f706f73616c604482015270081a5cc81b9bdd0818dbdb5c1b195d1959607a1b6064820152608401610430565b6000868152602081905260408120805490919061252a9061413c565b918290555092505b50505b60009384526001602081815260408087208488529091529094209384019290925560069092019190915590565b6000806000806000808660600151905060008760400151905060008860800151516001600160401b0381111561259a5761259a613ee2565b6040519080825280602002602001820160405280156125c3578160200160208202803683370190505b5060a08a015190915060005b825181101561262c578a6080015181815181106125ee576125ee614126565b60200260200101518051906020012083828151811061260f5761260f614126565b6020908102919091010152806126248161413c565b9150506125cf565b5082516020908102848201208551820286830120845183028584012084518402858501208e518f860151604080517f1463f426c05aff2c1a7a0957a71c9898bc8b47142540538e79ee25ee911413509881019890985287019190915260608601526080850184905260a0850183905260c0850182905260e08501819052929b509099509750955061010001611d77565b8051602090810291810191909120604080517feea5e3908ac28cbdbbce8853e49444c558a0a03597e98ef19e6ff86162ed9ae38185015280820194909452606080850192909252805180850390920182526080909301909252815191012090565b600080600061272e87878787613107565b9150915061273b816131f4565b5095945050505050565b600080600061275c6003546001600160a01b031690565b604080516001600160a01b03878116602480840191909152835180840382018152604490930184526020830180516001600160e01b0316635624191160e01b1790529251931692634bb5274a926127b4929101614236565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516127ed91906141ee565b600060405180830381855afa9150503d8060008114612828576040519150601f19603f3d011682016040523d82523d6000602084013e61282d565b606091505b50915091508161113d5760405162461bcd60e51b815260206004820152604260248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c206067657460448201527f427269646765566f74657257656967687428616464726573732960206661696c606482015261195960f21b608482015260a401610430565b6001600160a01b03841660009081526002860160205260408120541561291a576128e4856001600160a01b031660146133aa565b6040516020016128f49190614905565b60408051601f198184030181529082905262461bcd60e51b825261043091600401614236565b6001600160a01b0385166000908152600287016020908152604080832085905584835260038901909152812080548691908390612958908490614113565b925050819055905083811015801561298557506000875460ff16600381111561298357612983613b5c565b145b1561299d57865460ff19166001908117885587018390555b5050935460ff16949350505050565b600080825460ff1660038111156129c5576129c5613b5c565b1480156129d6575042826006015411155b90508015612b375760018201546040517f58f98006a7f2f253f8ae8f8b7cec9008ca05359633561cd7c22f3005682d4a5590600090a260005b6004830154811015612a7f57826007016000846004018381548110612a3657612a36614126565b60009182526020808320909101546001600160a01b031683528201929092526040018120805460ff19168155600181018290556002015580612a778161413c565b915050612a0f565b5060005b6005830154811015612af357826007016000846005018381548110612aaa57612aaa614126565b60009182526020808320909101546001600160a01b031683528201929092526040018120805460ff19168155600181018290556002015580612aeb8161413c565b915050612a83565b50815460ff191682556000600183018190556002830181905560038301819055612b219060048401906138ac565b612b2f6005830160006138ac565b600060068301555b919050565b612b4461386f565b6000612b51868686612172565b9150612b686002548361233890919063ffffffff16565b6000612b7383611bfd565b9050612b856000828960200151612434565b83519092508214612ba85760405162461bcd60e51b81526004016104309061486a565b80827f771d78ae9e5fca95a532fb0971d575d0ce9b59d14823c063e08740137e0e0eca85612bd58b612562565b8b89604051612be79493929190614568565b60405180910390a35094509492505050565b6000806000612c106003546001600160a01b031690565b6040805160048152602480820183526020820180516001600160e01b031663926323d560e01b17905291516001600160a01b039390931692634bb5274a92612c59929101614236565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051612c9291906141ee565b600060405180830381855afa9150503d8060008114612ccd576040519150601f19603f3d011682016040523d82523d6000602084013e612cd2565b606091505b5091509150816115d15760405162461bcd60e51b815260206004820152603360248201527f476f7665726e616e636541646d696e3a2070726f78792063616c6c2060746f74604482015272185b15d95a59da1d1cca0a580819985a5b1959606a1b6064820152608401610430565b60208088015188516000828152600184526040808220838352909452928320612d68816129ac565b15612d7957600193505050506130fc565b6020808c015160009081529081905260409020548214612df45760405162461bcd60e51b815260206004820152603060248201527f436f7265476f7665726e616e63653a20717565727920666f7220696e76616c6960448201526f642070726f706f73616c206e6f6e636560801b6064820152608401610430565b6000815460ff166003811115612e0c57612e0c613b5c565b14612e675760405162461bcd60e51b815260206004820152602560248201527f436f7265476f7665726e616e63653a2074686520766f74652069732066696e616044820152641b1a5e995960da1b6064820152608401610430565b6001600160a01b038716600090815260078201602052604090206001015415612eae57612e9e876001600160a01b031660146133aa565b6040516020016128f49190614959565b6001600160a01b03871660008181526007830160209081526040918290208951815460ff191660ff909116178155908901516001808301919091558983015160029092019190915583015490517f1203f9e81c814a35f5f4cc24087b2a24c6fb7986a9f1406b68a9484882c93a2390612f2a908e908a906149a9565b60405180910390a3600080808c6001811115612f4857612f48613b5c565b03612f9d576004830180546001810182556000918252602082200180546001600160a01b0319166001600160a01b038c16179055600384018054899290612f90908490614113565b925050819055915061305c565b60018c6001811115612fb157612fb1613b5c565b03613006576005830180546001810182556000918252602082200180546001600160a01b0319166001600160a01b038c16179055600284018054899290612ff9908490614113565b925050819055905061305c565b60405162461bcd60e51b815260206004820152602560248201527f436f7265476f7665726e616e63653a20756e737570706f7274656420766f7465604482015264207479706560d81b6064820152608401610430565b8a82106130b057825460ff19166001908117845580840154604051919750907f5c819725ea53655a3b898f3df59b66489761935454e9212ca1e5ebd759953d0b90600090a26130ab838e613545565b6130f6565b8981106130f657825460ff19166003178355600180840154604051919750907f55295d4ce992922fa2e5ffbf3a3dcdb367de0a15e125ace083456017fd22060f90600090a25b50505050505b979650505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561313e57506000905060036131eb565b8460ff16601b1415801561315657508460ff16601c14155b1561316757506000905060046131eb565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156131bb573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166131e4576000600192509250506131eb565b9150600090505b94509492505050565b600081600481111561320857613208613b5c565b036132105750565b600181600481111561322457613224613b5c565b036132715760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610430565b600281600481111561328557613285613b5c565b036132d25760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610430565b60038160048111156132e6576132e6613b5c565b0361333e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610430565b600481600481111561335257613352613b5c565b036105aa5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610430565b606060006133b98360026149c0565b6133c4906002614113565b6001600160401b038111156133db576133db613ee2565b6040519080825280601f01601f191660200182016040528015613405576020820181803683370190505b509050600360fc1b8160008151811061342057613420614126565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061344f5761344f614126565b60200101906001600160f81b031916908160001a90535060006134738460026149c0565b61347e906001614113565b90505b60018111156134f6576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106134b2576134b2614126565b1a60f81b8282815181106134c8576134c8614126565b60200101906001600160f81b031916908160001a90535060049490941c936134ef816149d7565b9050613481565b5083156104865760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610430565b61354e816135b2565b15610d6157815460ff1916600217825560008061356a836135cc565b9150915083600101547fe134987599ae266ec90edeff1b26125b287dbb57b10822649432d1bb26537fba83836040516135a49291906149ee565b60405180910390a250505050565b600081602001516000148061048957505060200151461490565b6060806135d8836135b2565b6136305760405162461bcd60e51b815260206004820152602360248201527f50726f706f73616c3a20717565727920666f7220696e76616c696420636861696044820152621b925960ea1b6064820152608401610430565b8260600151516001600160401b0381111561364d5761364d613ee2565b604051908082528060200260200182016040528015613676578160200160208202803683370190505b5091508260600151516001600160401b0381111561369657613696613ee2565b6040519080825280602002602001820160405280156136c957816020015b60608152602001906001900390816136b45790505b50905060005b836060015151811015613869578360c0015181815181106136f2576136f2614126565b60200260200101515a116137485760405162461bcd60e51b815260206004820152601a60248201527f50726f706f73616c3a20696e73756666696369656e74206761730000000000006044820152606401610430565b8360600151818151811061375e5761375e614126565b60200260200101516001600160a01b03168460800151828151811061378557613785614126565b60200260200101518560c0015183815181106137a3576137a3614126565b6020026020010151908660a0015184815181106137c2576137c2614126565b60200260200101516040516137d791906141ee565b600060405180830381858888f193505050503d8060008114613815576040519150601f19603f3d011682016040523d82523d6000602084013e61381a565b606091505b5084838151811061382d5761382d614126565b6020026020010184848151811061384657613846614126565b602090810291909101019190915290151590526138628161413c565b90506136cf565b50915091565b6040518060e00160405280600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b50805460008255906000526020600020908101906105aa91905b808211156138da57600081556001016138c6565b5090565b60008083601f8401126138f057600080fd5b5081356001600160401b0381111561390757600080fd5b6020830191508360208260051b850101111561392257600080fd5b9250929050565b60008083601f84011261393b57600080fd5b5081356001600160401b0381111561395257600080fd5b60208301915083602060608302850101111561392257600080fd5b60008060008060006060868803121561398557600080fd5b85356001600160401b038082111561399c57600080fd5b9087019060e0828a0312156139b057600080fd5b909550602087013590808211156139c657600080fd5b6139d289838a016138de565b909650945060408801359150808211156139eb57600080fd5b506139f888828901613929565b969995985093965092949392505050565b6001600160a01b03811681146105aa57600080fd5b60008060408385031215613a3157600080fd5b823591506020830135613a4381613a09565b809150509250929050565b600080600080600080600080600060a08a8c031215613a6c57600080fd5b8935985060208a01356001600160401b0380821115613a8a57600080fd5b613a968d838e016138de565b909a50985060408c0135915080821115613aaf57600080fd5b613abb8d838e016138de565b909850965060608c0135915080821115613ad457600080fd5b613ae08d838e016138de565b909650945060808c0135915080821115613af957600080fd5b50613b068c828d016138de565b915080935050809150509295985092959850929598565b600060208284031215613b2f57600080fd5b813561048681613a09565b60008060408385031215613b4d57600080fd5b50508035926020909101359150565b634e487b7160e01b600052602160045260246000fd5b600281106105aa576105aa613b5c565b600081518084526020808501945080840160005b83811015613bcb578151805160ff16885283810151848901526040908101519088015260609096019590820190600101613b96565b509495945050505050565b604080825283519082018190526000906020906060840190828701845b82811015613c18578151613c0681613b72565b84529284019290840190600101613bf3565b50505083810382850152613c2c8186613b82565b9695505050505050565b600080600060608486031215613c4b57600080fd5b83359250602084013591506040840135613c6481613a09565b809150509250925092565b600060208284031215613c8157600080fd5b5035919050565b600080600080600060608688031215613ca057600080fd5b85356001600160401b0380821115613cb757600080fd5b9087019060c0828a0312156139b057600080fd5b600080600060408486031215613ce057600080fd5b8335925060208401356001600160401b03811115613cfd57600080fd5b613d09868287016138de565b9497909650939450505050565b6020815260006104866020830184613b82565b600080600080600060608688031215613d4157600080fd5b8535945060208601356001600160401b03808211156139c657600080fd5b60008060408385031215613d7257600080fd5b8235613d7d81613a09565b91506020830135613a4381613a09565b60008060008060008060008060008060c08b8d031215613dac57600080fd5b8a35995060208b0135985060408b01356001600160401b0380821115613dd157600080fd5b613ddd8e838f016138de565b909a50985060608d0135915080821115613df657600080fd5b613e028e838f016138de565b909850965060808d0135915080821115613e1b57600080fd5b613e278e838f016138de565b909650945060a08d0135915080821115613e4057600080fd5b50613e4d8d828e016138de565b915080935050809150509295989b9194979a5092959850565b60a0810160048710613e7a57613e7a613b5c565b95815260208101949094526040840192909252606083015260809091015290565b60208082526027908201527f476f7665726e616e636541646d696e3a2073656e646572206973206e6f74206760408201526637bb32b93737b960c91b606082015260800190565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b0381118282101715613f1a57613f1a613ee2565b60405290565b60405160c081016001600160401b0381118282101715613f1a57613f1a613ee2565b604051601f8201601f191681016001600160401b0381118282101715613f6a57613f6a613ee2565b604052919050565b60006001600160401b03821115613f8b57613f8b613ee2565b5060051b60200190565b6000613fa8613fa384613f72565b613f42565b8381529050602080820190600585901b840186811115613fc757600080fd5b845b8181101561405a5780356001600160401b0380821115613fe95760008081fd5b8188019150601f8a81840112613fff5760008081fd5b82358281111561401157614011613ee2565b614022818301601f19168801613f42565b92508083528b8782860101111561403b57600091508182fd5b8087850188850137600090830187015250855250928201928201613fc9565b505050509392505050565b6000610486368484613f95565b60208082526027908201527f476f7665726e616e636541646d696e3a206f6e6c7920616c6c6f7765642073656040820152661b198b58d85b1b60ca1b606082015260800190565b60208082526024908201527f476f7665726e616e636541646d696e3a2073657420746f206e6f6e2d636f6e746040820152631c9858dd60e21b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b80820180821115610489576104896140fd565b634e487b7160e01b600052603260045260246000fd5b60006001820161414e5761414e6140fd565b5060010190565b60006020828403121561416757600080fd5b815161048681613a09565b83815260406020808301829052908201839052600090849060608401835b868110156141be5783356141a381613a09565b6001600160a01b031682529282019290820190600101614190565b50979650505050505050565b60005b838110156141e55781810151838201526020016141cd565b50506000910152565b600082516142008184602087016141ca565b9190910192915050565b600081518084526142228160208601602086016141ca565b601f01601f19169290920160200192915050565b602081526000610486602083018461420a565b60006020828403121561425b57600080fd5b5051919050565b600082601f83011261427357600080fd5b81356020614283613fa383613f72565b82815260059290921b840181019181810190868411156142a257600080fd5b8286015b848110156142c65780356142b981613a09565b83529183019183016142a6565b509695505050505050565b600082601f8301126142e257600080fd5b813560206142f2613fa383613f72565b82815260059290921b8401810191818101908684111561431157600080fd5b8286015b848110156142c65780358352918301918301614315565b600082601f83011261433d57600080fd5b61048683833560208501613f95565b600060e0823603121561435e57600080fd5b614366613ef8565b82358152602083013560208201526040830135604082015260608301356001600160401b038082111561439857600080fd5b6143a436838701614262565b606084015260808501359150808211156143bd57600080fd5b6143c9368387016142d1565b608084015260a08501359150808211156143e257600080fd5b6143ee3683870161432c565b60a084015260c085013591508082111561440757600080fd5b50614414368286016142d1565b60c08301525092915050565b600081518084526020808501945080840160005b83811015613bcb57815187529582019590820190600101614434565b600081518084526020808501808196508360051b8101915082860160005b8581101561449857828403895261448684835161420a565b9885019893509084019060010161446e565b5091979650505050505050565b600060e08301825184526020808401518186015260408401516040860152606084015160e06060870152828151808552610100880191508383019450600092505b8083101561450f5784516001600160a01b031682529383019360019290920191908301906144e6565b506080860151935086810360808801526145298185614420565b935050505060a083015184820360a08601526145458282614450565b91505060c083015184820360c086015261455f8282614420565b95945050505050565b60808152600061457b60808301876144a5565b60208681850152838203604085015260c08201865183528187015182840152604087015160c0604085015281815180845260e0860191508483019350600092505b808310156145e55783516145cf81613b72565b82529284019260019290920191908401906145bc565b506060890151935084810360608601526145ff8185614420565b93505050506080860151828203608084015261461b8282614450565b91505060a086015182820360a08401526146358282614420565b935050505061455f60608301846001600160a01b03169052565b6020808252602f908201527f476f7665726e616e636541646d696e3a206361737420766f746520666f72206960408201526e1b9d985b1a59081c1c9bdc1bdcd85b608a1b606082015260800190565b600281106105aa57600080fd5b600082601f8301126146bc57600080fd5b813560206146cc613fa383613f72565b82815260059290921b840181019181810190868411156146eb57600080fd5b8286015b848110156142c65780356147028161469e565b83529183019183016146ef565b600060c0823603121561472157600080fd5b614729613f20565b823581526020830135602082015260408301356001600160401b038082111561475157600080fd5b61475d368387016146ab565b6040840152606085013591508082111561477657600080fd5b614782368387016142d1565b6060840152608085013591508082111561479b57600080fd5b6147a73683870161432c565b608084015260a08501359150808211156147c057600080fd5b506147cd368286016142d1565b60a08301525092915050565b6000606082840312156147eb57600080fd5b604051606081018181106001600160401b038211171561480d5761480d613ee2565b604052823560ff8116811461482157600080fd5b8152602083810135908201526040928301359281019290925250919050565b60408152600061485360408301856144a5565b905060018060a01b03831660208301529392505050565b60208082526026908201527f436f7265476f7665726e616e63653a20696e76616c69642070726f706f73616c604082015265206e6f6e636560d01b606082015260800190565b83815260208101839052606081016148c783613b72565b826040830152949350505050565b81810381811115610489576104896140fd565b6000602082840312156148fa57600080fd5b81356104868161469e565b73024b9b7b630ba32b223b7bb32b93730b731b29d160651b8152600082516149348160148501602087016141ca565b6d08185b1c9958591e481d9bdd195960921b6014939091019283015250602201919050565b6f021b7b932a3b7bb32b93730b731b29d160851b8152600082516149848160108501602087016141ca565b6d08185b1c9958591e481d9bdd195960921b6010939091019283015250601e01919050565b604081016149b684613b72565b9281526020015290565b8082028115828204841417610489576104896140fd565b6000816149e6576149e66140fd565b506000190190565b604080825283519082018190526000906020906060840190828701845b82811015614a29578151151584529284019290840190600101614a0b565b50505083810382850152613c2c818661445056fef8704f8860d9e985bf6c52ec4738bd10fe31487599b36c0944f746ea09dc256ba26469706673582212206d28c066dbd7031ca119cf1d6a454f01cf9481a218158d2145b1f9fdc5e70f3e64736f6c63430008110033", "devdoc": { "events": { "BridgeOperatorsApproved(uint256,address[])": { @@ -1314,7 +1314,7 @@ "label": "_roninTrustedOrganizationContract", "offset": 0, "slot": "3", - "type": "t_contract(IRoninTrustedOrganization)9772" + "type": "t_contract(IRoninTrustedOrganization)9778" }, { "astId": 5762, @@ -1322,7 +1322,7 @@ "label": "_bridgeContract", "offset": 0, "slot": "4", - "type": "t_contract(IBridge)8924" + "type": "t_contract(IBridge)8930" }, { "astId": 6650, @@ -1354,7 +1354,7 @@ "label": "_votingSig", "offset": 0, "slot": "8", - "type": "t_mapping(t_uint256,t_mapping(t_address,t_struct(Signature)10092_storage))" + "type": "t_mapping(t_uint256,t_mapping(t_address,t_struct(Signature)10098_storage))" } ], "types": { @@ -1374,17 +1374,17 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_contract(IBridge)8924": { + "t_contract(IBridge)8930": { "encoding": "inplace", "label": "contract IBridge", "numberOfBytes": "20" }, - "t_contract(IRoninTrustedOrganization)9772": { + "t_contract(IRoninTrustedOrganization)9778": { "encoding": "inplace", "label": "contract IRoninTrustedOrganization", "numberOfBytes": "20" }, - "t_enum(VoteStatus)10100": { + "t_enum(VoteStatus)10106": { "encoding": "inplace", "label": "enum VoteStatusConsumer.VoteStatus", "numberOfBytes": "1" @@ -1396,12 +1396,12 @@ "numberOfBytes": "32", "value": "t_bytes32" }, - "t_mapping(t_address,t_struct(Signature)10092_storage)": { + "t_mapping(t_address,t_struct(Signature)10098_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct SignatureConsumer.Signature)", "numberOfBytes": "32", - "value": "t_struct(Signature)10092_storage" + "value": "t_struct(Signature)10098_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -1417,12 +1417,12 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_mapping(t_uint256,t_mapping(t_address,t_struct(Signature)10092_storage))": { + "t_mapping(t_uint256,t_mapping(t_address,t_struct(Signature)10098_storage))": { "encoding": "mapping", "key": "t_uint256", "label": "mapping(uint256 => mapping(address => struct SignatureConsumer.Signature))", "numberOfBytes": "32", - "value": "t_mapping(t_address,t_struct(Signature)10092_storage)" + "value": "t_mapping(t_address,t_struct(Signature)10098_storage)" }, "t_mapping(t_uint256,t_mapping(t_uint256,t_struct(ProposalVote)7093_storage))": { "encoding": "mapping", @@ -1462,7 +1462,7 @@ "label": "status", "offset": 0, "slot": "0", - "type": "t_enum(VoteStatus)10100" + "type": "t_enum(VoteStatus)10106" }, { "astId": 6511, @@ -1501,7 +1501,7 @@ "label": "status", "offset": 0, "slot": "0", - "type": "t_enum(VoteStatus)10100" + "type": "t_enum(VoteStatus)10106" }, { "astId": 7075, @@ -1557,17 +1557,17 @@ "label": "sig", "offset": 0, "slot": "7", - "type": "t_mapping(t_address,t_struct(Signature)10092_storage)" + "type": "t_mapping(t_address,t_struct(Signature)10098_storage)" } ], "numberOfBytes": "256" }, - "t_struct(Signature)10092_storage": { + "t_struct(Signature)10098_storage": { "encoding": "inplace", "label": "struct SignatureConsumer.Signature", "members": [ { - "astId": 10087, + "astId": 10093, "contract": "contracts/ronin/RoninGovernanceAdmin.sol:RoninGovernanceAdmin", "label": "v", "offset": 0, @@ -1575,7 +1575,7 @@ "type": "t_uint8" }, { - "astId": 10089, + "astId": 10095, "contract": "contracts/ronin/RoninGovernanceAdmin.sol:RoninGovernanceAdmin", "label": "r", "offset": 0, @@ -1583,7 +1583,7 @@ "type": "t_bytes32" }, { - "astId": 10091, + "astId": 10097, "contract": "contracts/ronin/RoninGovernanceAdmin.sol:RoninGovernanceAdmin", "label": "s", "offset": 0, diff --git a/deployments/ronin-testnet/StakingLogic.json b/deployments/ronin-testnet/StakingLogic.json index 9b0566bab..791435d5e 100644 --- a/deployments/ronin-testnet/StakingLogic.json +++ b/deployments/ronin-testnet/StakingLogic.json @@ -1,5 +1,5 @@ { - "address": "0x6C497568b7799aE5f57353E904104a5bDadDA4d8", + "address": "0x84b089B600Bf550e1e70d2b9caa234EACcCA6b1F", "abi": [ { "inputs": [], @@ -626,6 +626,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolAdminAddr", + "type": "address" + } + ], + "name": "getPoolAddressOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -1020,41 +1039,41 @@ "type": "receive" } ], - "transactionHash": "0x21dfc44f7e166ee6bfb58be389f84f6ce5b8efe55e6ff92904aabb9ec9c9e0f9", + "transactionHash": "0xe41e107a06edd8d0c19148f194c7f87133715c47fd415b4c4884e155281cf916", "receipt": { "to": null, "from": "0x968D0Cd7343f711216817E617d3f92a23dC91c07", - "contractAddress": "0x6C497568b7799aE5f57353E904104a5bDadDA4d8", + "contractAddress": "0x84b089B600Bf550e1e70d2b9caa234EACcCA6b1F", "transactionIndex": 0, - "gasUsed": "3469606", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x9df264d4b2810e6e266d71f98d1cc81a839591bd1704fca67a806afe76d27944", - "transactionHash": "0x21dfc44f7e166ee6bfb58be389f84f6ce5b8efe55e6ff92904aabb9ec9c9e0f9", + "gasUsed": "3486409", + "logsBloom": "0x00000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000880000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xe90d2cff935ade3e1b4a33ef45fa6414a6f25462599691f6734ceb0022341a39", + "transactionHash": "0xe41e107a06edd8d0c19148f194c7f87133715c47fd415b4c4884e155281cf916", "logs": [ { "transactionIndex": 0, - "blockNumber": 12502969, - "transactionHash": "0x21dfc44f7e166ee6bfb58be389f84f6ce5b8efe55e6ff92904aabb9ec9c9e0f9", - "address": "0x6C497568b7799aE5f57353E904104a5bDadDA4d8", + "blockNumber": 12507950, + "transactionHash": "0xe41e107a06edd8d0c19148f194c7f87133715c47fd415b4c4884e155281cf916", + "address": "0x84b089B600Bf550e1e70d2b9caa234EACcCA6b1F", "topics": [ "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" ], "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", "logIndex": 0, - "blockHash": "0x9df264d4b2810e6e266d71f98d1cc81a839591bd1704fca67a806afe76d27944" + "blockHash": "0xe90d2cff935ade3e1b4a33ef45fa6414a6f25462599691f6734ceb0022341a39" } ], - "blockNumber": 12502969, - "cumulativeGasUsed": "3469606", + "blockNumber": 12507950, + "cumulativeGasUsed": "3486409", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "9ed9cfd78768299e018b7787a7a517a7", - "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"minSecs\",\"type\":\"uint256\"}],\"name\":\"CooldownSecsToUndelegateUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"consensuAddr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Delegated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"name\":\"MinValidatorStakingAmountUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"validator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"PoolApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"poolAddr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"shares\",\"type\":\"uint256\"}],\"name\":\"PoolSharesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"validator\",\"type\":\"address[]\"}],\"name\":\"PoolsDeprecated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"poolAddrs\",\"type\":\"address[]\"}],\"name\":\"PoolsUpdateConflicted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"poolAddrs\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"rewards\",\"type\":\"uint256[]\"}],\"name\":\"PoolsUpdateFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"poolAddrs\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"aRps\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"shares\",\"type\":\"uint256[]\"}],\"name\":\"PoolsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"poolAddr\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"RewardClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"consensuAddr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Staked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"validator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"contractBalance\",\"type\":\"uint256\"}],\"name\":\"StakingAmountDeductFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"validator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"contractBalance\",\"type\":\"uint256\"}],\"name\":\"StakingAmountTransferFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"consensuAddr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Undelegated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"consensuAddr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Unstaked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"poolAddr\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"debited\",\"type\":\"uint256\"}],\"name\":\"UserRewardUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"ValidatorContractUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"secs\",\"type\":\"uint256\"}],\"name\":\"WaitingSecsToRevokeUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_candidateAdmin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_consensusAddr\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_treasuryAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bridgeOperatorAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_commissionRate\",\"type\":\"uint256\"}],\"name\":\"applyValidatorCandidate\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_consensusAddrs\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_amounts\",\"type\":\"uint256[]\"}],\"name\":\"bulkUndelegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_consensusAddrList\",\"type\":\"address[]\"}],\"name\":\"claimRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"cooldownSecsToUndelegate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensusAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"deductStakingAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_actualDeductingAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensusAddr\",\"type\":\"address\"}],\"name\":\"delegate\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_consensusAddrList\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"_consensusAddrDst\",\"type\":\"address\"}],\"name\":\"delegateRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_pools\",\"type\":\"address[]\"}],\"name\":\"deprecatePools\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_pools\",\"type\":\"address[]\"}],\"name\":\"getManySelfStakings\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_selfStakings\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_poolAddrs\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_userList\",\"type\":\"address[]\"}],\"name\":\"getManyStakingAmounts\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_stakingAmounts\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_poolList\",\"type\":\"address[]\"}],\"name\":\"getManyStakingTotals\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_stakingAmounts\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getReward\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"_poolAddrList\",\"type\":\"address[]\"}],\"name\":\"getRewards\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_rewards\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getStakingAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddr\",\"type\":\"address\"}],\"name\":\"getStakingPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_stakingAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_stakingTotal\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddr\",\"type\":\"address\"}],\"name\":\"getStakingTotal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"__validatorContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"__minValidatorStakingAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"__cooldownSecsToUndelegate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"__waitingSecsToRevoke\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAdminAddr\",\"type\":\"address\"}],\"name\":\"isActivePoolAdmin\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minValidatorStakingAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_consensusAddrs\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_rewards\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_period\",\"type\":\"uint256\"}],\"name\":\"recordRewards\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensusAddrSrc\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_consensusAddrDst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"redelegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensusAddr\",\"type\":\"address\"}],\"name\":\"requestRenounce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensusAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_effectiveDaysOnwards\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_commissionRate\",\"type\":\"uint256\"}],\"name\":\"requestUpdateCommissionRate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_cooldownSecs\",\"type\":\"uint256\"}],\"name\":\"setCooldownSecsToUndelegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"setMinValidatorStakingAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"setValidatorContract\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_secs\",\"type\":\"uint256\"}],\"name\":\"setWaitingSecsToRevoke\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensusAddr\",\"type\":\"address\"}],\"name\":\"stake\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensusAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"undelegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensusAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unstake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validatorContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"waitingSecsToRevoke\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"applyValidatorCandidate(address,address,address,address,uint256)\":{\"details\":\"Proposes a candidate to become a validator. Requirements: - The method caller is able to receive RON. - The treasury is able to receive RON. - The amount is larger than or equal to the minimum validator staking amount `minValidatorStakingAmount()`. Emits the event `PoolApproved`.\",\"params\":{\"_candidateAdmin\":\"the candidate admin will be stored in the validator contract, used for calling function that affects to its candidate, e.g. scheduling maintenance.\"}},\"bulkUndelegate(address[],uint256[])\":{\"details\":\"Bulk unstakes from a list of candidates. Requirements: - The method caller is not the pool admin. Emits the events `Undelegated`.\"},\"claimRewards(address[])\":{\"details\":\"Claims the reward of method caller. Emits the `RewardClaimed` event.\"},\"cooldownSecsToUndelegate()\":{\"details\":\"Returns The cooldown time in seconds to undelegate from the last timestamp (s)he delegated.\"},\"deductStakingAmount(address,uint256)\":{\"details\":\"Deducts from staking amount of the validator `_consensusAddr` for `_amount`. Requirements: - The method caller is validator contract. Emits the event `Unstaked`.\"},\"delegate(address)\":{\"details\":\"Stakes for a validator candidate `_consensusAddr`. Requirements: - The consensus address is a validator candidate. - The method caller is not the pool admin. Emits the `Delegated` event.\"},\"delegateRewards(address[],address)\":{\"details\":\"Claims the rewards and delegates them to the consensus address. Requirements: - The method caller is not the pool admin. - The consensus address `_consensusAddrDst` is a validator candidate. Emits the `RewardClaimed` event and the `Delegated` event.\"},\"deprecatePools(address[])\":{\"details\":\"Deprecates the pool. - Deduct self-staking amount of the pool admin to zero. - Transfer the deducted amount to the pool admin. - Deactivate the pool admin address in the mapping of active pool admins Requirements: - The method caller is validator contract. Emits the event `PoolsDeprecated` and `Unstaked` events. Emits the event `StakingAmountTransferFailed` if the contract cannot transfer RON back to the pool admin.\"},\"getManySelfStakings(address[])\":{\"details\":\"Returns the self-staking amounts of the pools.\"},\"getManyStakingAmounts(address[],address[])\":{\"details\":\"Returns the staking amounts of the users.\"},\"getManyStakingTotals(address[])\":{\"details\":\"Returns the total staking amounts of all users for the pools `_poolAddrs`.\"},\"getReward(address,address)\":{\"details\":\"Returns the reward amount that user claimable.\"},\"getRewards(address,address[])\":{\"details\":\"Returns the claimable reward of the user `_user`.\"},\"getStakingAmount(address,address)\":{\"details\":\"Returns the staking amount of an user.\"},\"getStakingPool(address)\":{\"details\":\"Returns the staking pool detail.\"},\"getStakingTotal(address)\":{\"details\":\"Returns the total staking amount of all users for a pool.\"},\"initialize(address,uint256,uint256,uint256)\":{\"details\":\"Initializes the contract storage.\"},\"isActivePoolAdmin(address)\":{\"details\":\"Returns whether the `_poolAdminAddr` is currently active.\"},\"minValidatorStakingAmount()\":{\"details\":\"Returns the minimum threshold for being a validator candidate.\"},\"recordRewards(address[],uint256[],uint256)\":{\"details\":\"Records the amount of rewards `_rewards` for the pools `_consensusAddrs`. Requirements: - The method caller is validator contract. Emits the event `PoolsUpdated` once the contract recorded the rewards successfully. Emits the event `PoolsUpdateFailed` once the input array lengths are not equal. Emits the event `PoolsUpdateConflicted` when there are some pools which already updated in the period. Note: This method should be called once at the period ending.\"},\"redelegate(address,address,uint256)\":{\"details\":\"Unstakes an amount of RON from the `_consensusAddrSrc` and stake for `_consensusAddrDst`. Requirements: - The method caller is not the pool admin. - The consensus address `_consensusAddrDst` is a validator candidate. Emits the `Undelegated` event and the `Delegated` event.\"},\"requestRenounce(address)\":{\"details\":\"Renounces being a validator candidate and takes back the delegating/staking amount. Requirements: - The consensus address is a validator candidate. - The method caller is the pool admin.\"},\"requestUpdateCommissionRate(address,uint256,uint256)\":{\"details\":\"Pool admin requests update validator commission rate. The request will be forwarded to the candidate manager contract, and the value is getting updated in {ICandidateManager-execRequestUpdateCommissionRate}. Requirements: - The consensus address is a validator candidate. - The method caller is the pool admin. - The `_effectiveDaysOnwards` must be equal to or larger than the {CandidateManager-_minEffectiveDaysOnwards}. - The `_rate` must be in range of [0_00; 100_00]. Emits the event `CommissionRateUpdated`.\"},\"setCooldownSecsToUndelegate(uint256)\":{\"details\":\"Sets the cooldown time in seconds to undelegate from the last timestamp (s)he delegated. Requirements: - The method caller is admin. Emits the event `CooldownSecsToUndelegateUpdated`.\"},\"setMinValidatorStakingAmount(uint256)\":{\"details\":\"Sets the minimum threshold for being a validator candidate. Requirements: - The method caller is admin. Emits the `MinValidatorStakingAmountUpdated` event.\"},\"setValidatorContract(address)\":{\"details\":\"Sets the validator contract. Requirements: - The method caller is admin. - The new address is a contract. Emits the event `ValidatorContractUpdated`.\"},\"setWaitingSecsToRevoke(uint256)\":{\"details\":\"Sets the number of seconds that a candidate must wait to be revoked. Requirements: - The method caller is admin. Emits the event `WaitingSecsToRevokeUpdated`.\"},\"stake(address)\":{\"details\":\"Self-delegates to the validator candidate `_consensusAddr`. Requirements: - The consensus address is a validator candidate. - The method caller is the pool admin. - The `msg.value` is larger than 0. Emits the event `Staked`.\"},\"undelegate(address,uint256)\":{\"details\":\"Unstakes from a validator candidate `_consensusAddr` for `_amount`. Requirements: - The method caller is not the pool admin. Emits the `Undelegated` event.\"},\"unstake(address,uint256)\":{\"details\":\"Unstakes from the validator candidate `_consensusAddr` for `_amount`. Requirements: - The consensus address is a validator candidate. - The method caller is the pool admin. Emits the event `Unstaked`.\"},\"validatorContract()\":{\"details\":\"Returns the validator contract.\"},\"waitingSecsToRevoke()\":{\"details\":\"Returns the number of seconds that a candidate must wait for the renounce request gets affected.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ronin/staking/Staking.sol\":\"Staking\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x0e9621f60b2faabe65549f7ed0f24e8853a45c1b7990d47e8160e523683f3935\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/extensions/RONTransferHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nabstract contract RONTransferHelper {\\n /**\\n * @dev See `_sendRON`.\\n * Reverts if the recipient does not receive RON.\\n */\\n function _transferRON(address payable _recipient, uint256 _amount) internal {\\n require(_sendRON(_recipient, _amount), \\\"RONTransfer: unable to transfer value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Send `_amount` RON to the address `_recipient`.\\n * Returns whether the recipient receives RON or not.\\n * Reverts once the contract balance is insufficient.\\n *\\n * Note: consider using `ReentrancyGuard` before calling this function.\\n *\\n */\\n function _sendRON(address payable _recipient, uint256 _amount) internal returns (bool _success) {\\n require(address(this).balance >= _amount, \\\"RONTransfer: insufficient balance\\\");\\n return _unsafeSendRON(_recipient, _amount);\\n }\\n\\n /**\\n * @dev Unsafe send `_amount` RON to the address `_recipient`. If the sender's balance is insufficient,\\n * the call does not revert.\\n *\\n * Note:\\n * - Does not assert whether the balance of sender is sufficient.\\n * - Does not assert whether the recipient accepts RON.\\n * - Consider using `ReentrancyGuard` before calling this function.\\n *\\n */\\n function _unsafeSendRON(address payable _recipient, uint256 _amount) internal returns (bool _success) {\\n (_success, ) = _recipient.call{ value: _amount }(\\\"\\\");\\n }\\n}\\n\",\"keccak256\":\"0xd2d20123d75f4d4ca6441a791a3eb1b546b5c8652119ffc8406a11c8ed16529e\",\"license\":\"MIT\"},\"contracts/extensions/collections/HasProxyAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/StorageSlot.sol\\\";\\n\\nabstract contract HasProxyAdmin {\\n // bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n modifier onlyAdmin() {\\n require(msg.sender == _getAdmin(), \\\"HasProxyAdmin: unauthorized sender\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns proxy admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n}\\n\",\"keccak256\":\"0x0c2fcf25290180e8cd733691b113464cdde671dc019e6c343e9eb3e16c6ca24a\",\"license\":\"MIT\"},\"contracts/extensions/collections/HasValidatorContract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./HasProxyAdmin.sol\\\";\\nimport \\\"../../interfaces/collections/IHasValidatorContract.sol\\\";\\nimport \\\"../../interfaces/validator/IRoninValidatorSet.sol\\\";\\n\\ncontract HasValidatorContract is IHasValidatorContract, HasProxyAdmin {\\n IRoninValidatorSet internal _validatorContract;\\n\\n modifier onlyValidatorContract() {\\n require(validatorContract() == msg.sender, \\\"HasValidatorContract: method caller must be validator contract\\\");\\n _;\\n }\\n\\n /**\\n * @inheritdoc IHasValidatorContract\\n */\\n function validatorContract() public view override returns (address) {\\n return address(_validatorContract);\\n }\\n\\n /**\\n * @inheritdoc IHasValidatorContract\\n */\\n function setValidatorContract(address _addr) external override onlyAdmin {\\n require(_addr.code.length > 0, \\\"HasValidatorContract: set to non-contract\\\");\\n _setValidatorContract(_addr);\\n }\\n\\n /**\\n * @dev Sets the validator contract.\\n *\\n * Emits the event `ValidatorContractUpdated`.\\n *\\n */\\n function _setValidatorContract(address _addr) internal {\\n _validatorContract = IRoninValidatorSet(_addr);\\n emit ValidatorContractUpdated(_addr);\\n }\\n}\\n\",\"keccak256\":\"0xfc2ef0f8358960702307626dc4ccbab066c5e0763e04e8a794f0dc4711789bdd\",\"license\":\"MIT\"},\"contracts/interfaces/collections/IHasValidatorContract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface IHasValidatorContract {\\n /// @dev Emitted when the validator contract is updated.\\n event ValidatorContractUpdated(address);\\n\\n /**\\n * @dev Returns the validator contract.\\n */\\n function validatorContract() external view returns (address);\\n\\n /**\\n * @dev Sets the validator contract.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n * - The new address is a contract.\\n *\\n * Emits the event `ValidatorContractUpdated`.\\n *\\n */\\n function setValidatorContract(address) external;\\n}\\n\",\"keccak256\":\"0xb6e39a02969091decbb50633286855c157502a7d15a988e436644b8d419e13d3\",\"license\":\"MIT\"},\"contracts/interfaces/consumers/PeriodWrapperConsumer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface PeriodWrapperConsumer {\\n struct PeriodWrapper {\\n // Inner value.\\n uint256 inner;\\n // Last period number that the info updated.\\n uint256 lastPeriod;\\n }\\n}\\n\",\"keccak256\":\"0xb6777e3c364306eb8d5355583c1aca44de9d351cb40ddf1cea832206d4aad272\",\"license\":\"MIT\"},\"contracts/interfaces/staking/IBaseStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface IBaseStaking {\\n struct PoolDetail {\\n // Address of the pool i.e. consensus address of the validator\\n address addr;\\n // Pool admin address\\n address admin;\\n // Self-staking amount\\n uint256 stakingAmount;\\n // Total number of RON staking for the pool\\n uint256 stakingTotal;\\n // Mapping from delegator => delegating amount\\n mapping(address => uint256) delegatingAmount;\\n // Mapping from delegator => the last timestamp that delegator staked\\n mapping(address => uint256) lastDelegatingTimestamp;\\n }\\n\\n /// @dev Emitted when the minium number of seconds to undelegate is updated.\\n event CooldownSecsToUndelegateUpdated(uint256 minSecs);\\n /// @dev Emitted when the number of seconds that a candidate must wait to be revoked.\\n event WaitingSecsToRevokeUpdated(uint256 secs);\\n\\n /**\\n * @dev Returns whether the `_poolAdminAddr` is currently active.\\n */\\n function isActivePoolAdmin(address _poolAdminAddr) external view returns (bool);\\n\\n /**\\n * @dev Returns The cooldown time in seconds to undelegate from the last timestamp (s)he delegated.\\n */\\n function cooldownSecsToUndelegate() external view returns (uint256);\\n\\n /**\\n * @dev Returns the number of seconds that a candidate must wait for the renounce request gets affected.\\n */\\n function waitingSecsToRevoke() external view returns (uint256);\\n\\n /**\\n * @dev Sets the cooldown time in seconds to undelegate from the last timestamp (s)he delegated.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n *\\n * Emits the event `CooldownSecsToUndelegateUpdated`.\\n *\\n */\\n function setCooldownSecsToUndelegate(uint256 _cooldownSecs) external;\\n\\n /**\\n * @dev Sets the number of seconds that a candidate must wait to be revoked.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n *\\n * Emits the event `WaitingSecsToRevokeUpdated`.\\n *\\n */\\n function setWaitingSecsToRevoke(uint256 _secs) external;\\n}\\n\",\"keccak256\":\"0xb903220353537f45b109b663df032dd818d984eb660453e1be38970dad9822ff\",\"license\":\"MIT\"},\"contracts/interfaces/staking/ICandidateStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"./IRewardPool.sol\\\";\\n\\ninterface ICandidateStaking is IRewardPool {\\n /// @dev Emitted when the minimum staking amount for being a validator is updated.\\n event MinValidatorStakingAmountUpdated(uint256 threshold);\\n\\n /// @dev Emitted when the pool admin staked for themself.\\n event Staked(address indexed consensuAddr, uint256 amount);\\n /// @dev Emitted when the pool admin unstaked the amount of RON from themself.\\n event Unstaked(address indexed consensuAddr, uint256 amount);\\n\\n /// @dev Emitted when the validator pool is approved.\\n event PoolApproved(address indexed validator, address indexed admin);\\n /// @dev Emitted when the validator pool is deprecated.\\n event PoolsDeprecated(address[] validator);\\n /// @dev Emitted when the staking amount transfer failed.\\n event StakingAmountTransferFailed(\\n address indexed validator,\\n address indexed admin,\\n uint256 amount,\\n uint256 contractBalance\\n );\\n /// @dev Emitted when the staking amount deducted failed, e.g. when the validator gets slashed.\\n event StakingAmountDeductFailed(\\n address indexed validator,\\n address indexed recipient,\\n uint256 amount,\\n uint256 contractBalance\\n );\\n\\n /**\\n * @dev Returns the minimum threshold for being a validator candidate.\\n */\\n function minValidatorStakingAmount() external view returns (uint256);\\n\\n /**\\n * @dev Sets the minimum threshold for being a validator candidate.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n *\\n * Emits the `MinValidatorStakingAmountUpdated` event.\\n *\\n */\\n function setMinValidatorStakingAmount(uint256) external;\\n\\n /**\\n * @dev Proposes a candidate to become a validator.\\n *\\n * Requirements:\\n * - The method caller is able to receive RON.\\n * - The treasury is able to receive RON.\\n * - The amount is larger than or equal to the minimum validator staking amount `minValidatorStakingAmount()`.\\n *\\n * Emits the event `PoolApproved`.\\n *\\n * @param _candidateAdmin the candidate admin will be stored in the validator contract, used for calling function that affects\\n * to its candidate, e.g. scheduling maintenance.\\n *\\n */\\n function applyValidatorCandidate(\\n address _candidateAdmin,\\n address _consensusAddr,\\n address payable _treasuryAddr,\\n address _bridgeOperatorAddr,\\n uint256 _commissionRate\\n ) external payable;\\n\\n /**\\n * @dev Deprecates the pool.\\n * - Deduct self-staking amount of the pool admin to zero.\\n * - Transfer the deducted amount to the pool admin.\\n * - Deactivate the pool admin address in the mapping of active pool admins\\n *\\n * Requirements:\\n * - The method caller is validator contract.\\n *\\n * Emits the event `PoolsDeprecated` and `Unstaked` events.\\n * Emits the event `StakingAmountTransferFailed` if the contract cannot transfer RON back to the pool admin.\\n *\\n */\\n function deprecatePools(address[] calldata _pools) external;\\n\\n /**\\n * @dev Self-delegates to the validator candidate `_consensusAddr`.\\n *\\n * Requirements:\\n * - The consensus address is a validator candidate.\\n * - The method caller is the pool admin.\\n * - The `msg.value` is larger than 0.\\n *\\n * Emits the event `Staked`.\\n *\\n */\\n function stake(address _consensusAddr) external payable;\\n\\n /**\\n * @dev Unstakes from the validator candidate `_consensusAddr` for `_amount`.\\n *\\n * Requirements:\\n * - The consensus address is a validator candidate.\\n * - The method caller is the pool admin.\\n *\\n * Emits the event `Unstaked`.\\n *\\n */\\n function unstake(address _consensusAddr, uint256 _amount) external;\\n\\n /**\\n * @dev Pool admin requests update validator commission rate. The request will be forwarded to the candidate manager\\n * contract, and the value is getting updated in {ICandidateManager-execRequestUpdateCommissionRate}.\\n *\\n * Requirements:\\n * - The consensus address is a validator candidate.\\n * - The method caller is the pool admin.\\n * - The `_effectiveDaysOnwards` must be equal to or larger than the {CandidateManager-_minEffectiveDaysOnwards}.\\n * - The `_rate` must be in range of [0_00; 100_00].\\n *\\n * Emits the event `CommissionRateUpdated`.\\n *\\n */\\n function requestUpdateCommissionRate(\\n address _consensusAddr,\\n uint256 _effectiveDaysOnwards,\\n uint256 _commissionRate\\n ) external;\\n\\n /**\\n * @dev Renounces being a validator candidate and takes back the delegating/staking amount.\\n *\\n * Requirements:\\n * - The consensus address is a validator candidate.\\n * - The method caller is the pool admin.\\n *\\n */\\n function requestRenounce(address _consensusAddr) external;\\n}\\n\",\"keccak256\":\"0x8ced5bc423094821a203e7100076868ca41a7176e0ebc0fd09d1fd5f6c5fac8a\",\"license\":\"MIT\"},\"contracts/interfaces/staking/IDelegatorStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"./IRewardPool.sol\\\";\\n\\ninterface IDelegatorStaking is IRewardPool {\\n /// @dev Emitted when the delegator staked for a validator candidate.\\n event Delegated(address indexed delegator, address indexed consensuAddr, uint256 amount);\\n /// @dev Emitted when the delegator unstaked from a validator candidate.\\n event Undelegated(address indexed delegator, address indexed consensuAddr, uint256 amount);\\n\\n /**\\n * @dev Stakes for a validator candidate `_consensusAddr`.\\n *\\n * Requirements:\\n * - The consensus address is a validator candidate.\\n * - The method caller is not the pool admin.\\n *\\n * Emits the `Delegated` event.\\n *\\n */\\n function delegate(address _consensusAddr) external payable;\\n\\n /**\\n * @dev Unstakes from a validator candidate `_consensusAddr` for `_amount`.\\n *\\n * Requirements:\\n * - The method caller is not the pool admin.\\n *\\n * Emits the `Undelegated` event.\\n *\\n */\\n function undelegate(address _consensusAddr, uint256 _amount) external;\\n\\n /**\\n * @dev Bulk unstakes from a list of candidates.\\n *\\n * Requirements:\\n * - The method caller is not the pool admin.\\n *\\n * Emits the events `Undelegated`.\\n *\\n */\\n function bulkUndelegate(address[] calldata _consensusAddrs, uint256[] calldata _amounts) external;\\n\\n /**\\n * @dev Unstakes an amount of RON from the `_consensusAddrSrc` and stake for `_consensusAddrDst`.\\n *\\n * Requirements:\\n * - The method caller is not the pool admin.\\n * - The consensus address `_consensusAddrDst` is a validator candidate.\\n *\\n * Emits the `Undelegated` event and the `Delegated` event.\\n *\\n */\\n function redelegate(\\n address _consensusAddrSrc,\\n address _consensusAddrDst,\\n uint256 _amount\\n ) external;\\n\\n /**\\n * @dev Returns the claimable reward of the user `_user`.\\n */\\n function getRewards(address _user, address[] calldata _poolAddrList)\\n external\\n view\\n returns (uint256[] memory _rewards);\\n\\n /**\\n * @dev Claims the reward of method caller.\\n *\\n * Emits the `RewardClaimed` event.\\n *\\n */\\n function claimRewards(address[] calldata _consensusAddrList) external returns (uint256 _amount);\\n\\n /**\\n * @dev Claims the rewards and delegates them to the consensus address.\\n *\\n * Requirements:\\n * - The method caller is not the pool admin.\\n * - The consensus address `_consensusAddrDst` is a validator candidate.\\n *\\n * Emits the `RewardClaimed` event and the `Delegated` event.\\n *\\n */\\n function delegateRewards(address[] calldata _consensusAddrList, address _consensusAddrDst)\\n external\\n returns (uint256 _amount);\\n}\\n\",\"keccak256\":\"0xc937036bcda0a4632af4937c514230a7b301d1f42959bfb00c377cb76f3f61bc\",\"license\":\"MIT\"},\"contracts/interfaces/staking/IRewardPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"../../interfaces/consumers/PeriodWrapperConsumer.sol\\\";\\n\\ninterface IRewardPool is PeriodWrapperConsumer {\\n struct UserRewardFields {\\n // Recorded reward amount.\\n uint256 debited;\\n // The last accumulated of the amount rewards per share (one unit staking) that the info updated.\\n uint256 aRps;\\n // Min staking amount in the period.\\n uint256 minAmount;\\n // Last period number that the info updated.\\n uint256 lastPeriod;\\n }\\n\\n struct PoolFields {\\n // Accumulated of the amount rewards per share (one unit staking).\\n uint256 aRps;\\n // The staking total to share reward of the current period.\\n PeriodWrapper shares;\\n }\\n\\n /// @dev Emitted when the fields to calculate pending reward for the user is updated.\\n event UserRewardUpdated(address indexed poolAddr, address indexed user, uint256 debited);\\n /// @dev Emitted when the user claimed their reward\\n event RewardClaimed(address indexed poolAddr, address indexed user, uint256 amount);\\n\\n /// @dev Emitted when the pool shares are updated\\n event PoolSharesUpdated(uint256 indexed period, address indexed poolAddr, uint256 shares);\\n /// @dev Emitted when the pools are updated\\n event PoolsUpdated(uint256 indexed period, address[] poolAddrs, uint256[] aRps, uint256[] shares);\\n /// @dev Emitted when the contract fails when updating the pools\\n event PoolsUpdateFailed(uint256 indexed period, address[] poolAddrs, uint256[] rewards);\\n /// @dev Emitted when the contract fails when updating the pools that already set\\n event PoolsUpdateConflicted(uint256 indexed period, address[] poolAddrs);\\n\\n /**\\n * @dev Returns the reward amount that user claimable.\\n */\\n function getReward(address _poolAddr, address _user) external view returns (uint256);\\n\\n /**\\n * @dev Returns the staking amount of an user.\\n */\\n function getStakingAmount(address _poolAddr, address _user) external view returns (uint256);\\n\\n /**\\n * @dev Returns the staking amounts of the users.\\n */\\n function getManyStakingAmounts(address[] calldata _poolAddrs, address[] calldata _userList)\\n external\\n view\\n returns (uint256[] memory);\\n\\n /**\\n * @dev Returns the total staking amount of all users for a pool.\\n */\\n function getStakingTotal(address _poolAddr) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total staking amounts of all users for the pools `_poolAddrs`.\\n */\\n function getManyStakingTotals(address[] calldata _poolAddrs) external view returns (uint256[] memory);\\n}\\n\",\"keccak256\":\"0x8a4d4ab84f0b343cea84b8e86f90f4b9286051a166e348f5ef6c7d2d2c2af09f\",\"license\":\"MIT\"},\"contracts/interfaces/staking/IStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"./IBaseStaking.sol\\\";\\nimport \\\"./ICandidateStaking.sol\\\";\\nimport \\\"./IDelegatorStaking.sol\\\";\\n\\ninterface IStaking is IRewardPool, IBaseStaking, ICandidateStaking, IDelegatorStaking {\\n /**\\n * @dev Records the amount of rewards `_rewards` for the pools `_consensusAddrs`.\\n *\\n * Requirements:\\n * - The method caller is validator contract.\\n *\\n * Emits the event `PoolsUpdated` once the contract recorded the rewards successfully.\\n * Emits the event `PoolsUpdateFailed` once the input array lengths are not equal.\\n * Emits the event `PoolsUpdateConflicted` when there are some pools which already updated in the period.\\n *\\n * Note: This method should be called once at the period ending.\\n *\\n */\\n function recordRewards(\\n address[] calldata _consensusAddrs,\\n uint256[] calldata _rewards,\\n uint256 _period\\n ) external payable;\\n\\n /**\\n * @dev Deducts from staking amount of the validator `_consensusAddr` for `_amount`.\\n *\\n * Requirements:\\n * - The method caller is validator contract.\\n *\\n * Emits the event `Unstaked`.\\n *\\n */\\n function deductStakingAmount(address _consensusAddr, uint256 _amount)\\n external\\n returns (uint256 _actualDeductingAmount);\\n\\n /**\\n * @dev Returns the staking pool detail.\\n */\\n function getStakingPool(address)\\n external\\n view\\n returns (\\n address _admin,\\n uint256 _stakingAmount,\\n uint256 _stakingTotal\\n );\\n\\n /**\\n * @dev Returns the self-staking amounts of the pools.\\n */\\n function getManySelfStakings(address[] calldata) external view returns (uint256[] memory);\\n}\\n\",\"keccak256\":\"0x84a3f7dfb1d291808514207da26c29fba58479a780d8f955e1cf5ea413fbba83\",\"license\":\"MIT\"},\"contracts/interfaces/validator/ICandidateManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface ICandidateManager {\\n struct ValidatorCandidate {\\n // Admin of the candidate\\n address admin;\\n // Address of the validator that produces block, e.g. block.coinbase. This is so-called validator address.\\n address consensusAddr;\\n // Address that receives mining reward of the validator\\n address payable treasuryAddr;\\n // Address of the bridge operator corresponding to the candidate\\n address bridgeOperatorAddr;\\n // The percentage of reward that validators can be received, the rest goes to the delegators.\\n // Values in range [0; 100_00] stands for 0-100%\\n uint256 commissionRate;\\n // The timestamp that scheduled to revoke the candidate (no schedule=0)\\n uint256 revokingTimestamp;\\n // The deadline that the candidate must top up staking amount to keep it larger than or equal to the threshold (no deadline=0)\\n uint256 topupDeadline;\\n }\\n\\n struct CommissionSchedule {\\n // The timestamp that the commission schedule gets affected (no schedule=0).\\n uint256 effectiveTimestamp;\\n // The new commission rate. Value is in range [0; 100_00], stands for 0-100%\\n uint256 commissionRate;\\n }\\n\\n /// @dev Emitted when the maximum number of validator candidates is updated.\\n event MaxValidatorCandidateUpdated(uint256 threshold);\\n /// @dev Emitted when the min offset to the effective date of commission rate change is updated.\\n event MinEffectiveDaysOnwardsUpdated(uint256 numOfDays);\\n /// @dev Emitted when the validator candidate is granted.\\n event CandidateGranted(\\n address indexed consensusAddr,\\n address indexed treasuryAddr,\\n address indexed admin,\\n address bridgeOperator\\n );\\n /// @dev Emitted when the revoking timestamp of a candidate is updated.\\n event CandidateRevokingTimestampUpdated(address indexed consensusAddr, uint256 revokingTimestamp);\\n /// @dev Emitted when the topup deadline of a candidate is updated.\\n event CandidateTopupDeadlineUpdated(address indexed consensusAddr, uint256 topupDeadline);\\n /// @dev Emitted when the validator candidate is revoked.\\n event CandidatesRevoked(address[] consensusAddrs);\\n\\n /// @dev Emitted when a schedule for updating commission rate is set.\\n event CommissionRateUpdateScheduled(address indexed consensusAddr, uint256 effectiveTimestamp, uint256 rate);\\n /// @dev Emitted when the commission rate of a validator is updated.\\n event CommissionRateUpdated(address indexed consensusAddr, uint256 rate);\\n\\n /**\\n * @dev Returns the maximum number of validator candidate.\\n */\\n function maxValidatorCandidate() external view returns (uint256);\\n\\n /**\\n * @dev Returns the minimum number of days to the effective date of commission rate change.\\n */\\n function minEffectiveDaysOnwards() external view returns (uint256);\\n\\n /**\\n * @dev Sets the maximum number of validator candidate.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n *\\n * Emits the `MaxValidatorCandidateUpdated` event.\\n *\\n */\\n function setMaxValidatorCandidate(uint256) external;\\n\\n /**\\n * @dev Sets the minimum number of days to the effective date of commision rate change.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n *\\n * Emits the `MinEffectiveDaysOnwardsUpdated` event.\\n *\\n */\\n function setMinEffectiveDaysOnwards(uint256 _numOfDays) external;\\n\\n /**\\n * @dev Grants a validator candidate.\\n *\\n * Requirements:\\n * - The method caller is staking contract.\\n *\\n * Emits the event `CandidateGranted`.\\n *\\n */\\n function grantValidatorCandidate(\\n address _admin,\\n address _consensusAddr,\\n address payable _treasuryAddr,\\n address _bridgeOperatorAddr,\\n uint256 _commissionRate\\n ) external;\\n\\n /**\\n * @dev Requests to revoke a validator candidate in next `_secsLeft` seconds.\\n *\\n * Requirements:\\n * - The method caller is staking contract.\\n *\\n * Emits the event `CandidateRevokingTimestampUpdated`.\\n *\\n */\\n function requestRevokeCandidate(address, uint256 _secsLeft) external;\\n\\n /**\\n * @dev Fallback function of `CandidateStaking-requestUpdateCommissionRate`.\\n *\\n * Requirements:\\n * - The method caller is the staking contract.\\n * - The `_effectiveTimestamp` must be the beginning of a UTC day, and at least from 7 days onwards\\n * - The `_rate` must be in range of [0_00; 100_00].\\n *\\n * Emits the event `CommissionRateUpdateScheduled`.\\n *\\n */\\n function execRequestUpdateCommissionRate(\\n address _consensusAddr,\\n uint256 _effectiveTimestamp,\\n uint256 _rate\\n ) external;\\n\\n /**\\n * @dev Returns whether the address is a validator (candidate).\\n */\\n function isValidatorCandidate(address _addr) external view returns (bool);\\n\\n /**\\n * @dev Returns the validator candidate.\\n */\\n function getValidatorCandidates() external view returns (address[] memory);\\n\\n /**\\n * @dev Returns all candidate info.\\n */\\n function getCandidateInfos() external view returns (ValidatorCandidate[] memory);\\n\\n /**\\n * @dev Returns the info of a candidate.\\n */\\n function getCandidateInfo(address _candidate) external view returns (ValidatorCandidate memory);\\n\\n /**\\n * @dev Returns whether the address is the candidate admin.\\n */\\n function isCandidateAdmin(address _candidate, address _admin) external view returns (bool);\\n\\n /**\\n * @dev Returns the schedule of changing commission rate of a candidate address.\\n */\\n function getCommissionChangeSchedule(address _candidate) external view returns (CommissionSchedule memory);\\n}\\n\",\"keccak256\":\"0xacfc4038d51b7746d66351009c6f25e277d45eafd23eb057441ed6884f91dd19\",\"license\":\"MIT\"},\"contracts/interfaces/validator/ICoinbaseExecution.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"./ISlashingExecution.sol\\\";\\n\\ninterface ICoinbaseExecution is ISlashingExecution {\\n enum BlockRewardDeprecatedType {\\n UNKNOWN,\\n UNAVAILABILITY,\\n AFTER_BAILOUT\\n }\\n\\n /// @dev Emitted when the validator set is updated\\n event ValidatorSetUpdated(uint256 indexed period, address[] consensusAddrs);\\n /// @dev Emitted when the bridge operator set is updated, to mirror the in-jail and maintaining status of the validator.\\n event BlockProducerSetUpdated(uint256 indexed period, address[] consensusAddrs);\\n /// @dev Emitted when the bridge operator set is updated.\\n event BridgeOperatorSetUpdated(uint256 indexed period, address[] bridgeOperators);\\n\\n /// @dev Emitted when the reward of the block producer is deprecated.\\n event BlockRewardDeprecated(\\n address indexed coinbaseAddr,\\n uint256 rewardAmount,\\n BlockRewardDeprecatedType deprecatedType\\n );\\n /// @dev Emitted when the block reward is submitted.\\n event BlockRewardSubmitted(address indexed coinbaseAddr, uint256 submittedAmount, uint256 bonusAmount);\\n\\n /// @dev Emitted when the block producer reward is distributed.\\n event MiningRewardDistributed(address indexed consensusAddr, address indexed recipient, uint256 amount);\\n /// @dev Emitted when the contract fails when distributing the block producer reward.\\n event MiningRewardDistributionFailed(\\n address indexed consensusAddr,\\n address indexed recipient,\\n uint256 amount,\\n uint256 contractBalance\\n );\\n\\n /// @dev Emitted when the bridge operator reward is distributed.\\n event BridgeOperatorRewardDistributed(\\n address indexed consensusAddr,\\n address indexed bridgeOperator,\\n address indexed recipientAddr,\\n uint256 amount\\n );\\n /// @dev Emitted when the contract fails when distributing the bridge operator reward.\\n event BridgeOperatorRewardDistributionFailed(\\n address indexed consensusAddr,\\n address indexed bridgeOperator,\\n address indexed recipient,\\n uint256 amount,\\n uint256 contractBalance\\n );\\n\\n /// @dev Emitted when the amount of RON reward is distributed to staking contract.\\n event StakingRewardDistributed(uint256 amount);\\n /// @dev Emitted when the contracts fails when distributing the amount of RON to the staking contract.\\n event StakingRewardDistributionFailed(uint256 amount, uint256 contractBalance);\\n\\n /// @dev Emitted when the epoch is wrapped up.\\n event WrappedUpEpoch(uint256 indexed periodNumber, uint256 indexed epochNumber, bool periodEnding);\\n\\n /**\\n * @dev Submits reward of the current block.\\n *\\n * Requirements:\\n * - The method caller is coinbase.\\n *\\n * Emits the event `MiningRewardDeprecated` if the coinbase is slashed or no longer be a block producer.\\n * Emits the event `BlockRewardSubmitted` for the valid call.\\n *\\n */\\n function submitBlockReward() external payable;\\n\\n /**\\n * @dev Wraps up the current epoch.\\n *\\n * Requirements:\\n * - The method must be called when the current epoch is ending.\\n * - The epoch is not wrapped yet.\\n * - The method caller is coinbase.\\n *\\n * Emits the event `MiningRewardDistributed` when some validator has reward distributed.\\n * Emits the event `StakingRewardDistributed` when some staking pool has reward distributed.\\n * Emits the event `BlockProducerSetUpdated` when the epoch is wrapped up.\\n * Emits the event `BridgeOperatorSetUpdated` when the epoch is wrapped up at period ending.\\n * Emits the event `ValidatorSetUpdated` when the epoch is wrapped up at period ending, and the validator set gets updated.\\n * Emits the event `WrappedUpEpoch`.\\n *\\n */\\n function wrapUpEpoch() external payable;\\n}\\n\",\"keccak256\":\"0xd0aef1d05e99c82fd733c97a45f3a999898c4ded0cace2cb901864e2ddc3904a\",\"license\":\"MIT\"},\"contracts/interfaces/validator/IRoninValidatorSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"./ICandidateManager.sol\\\";\\nimport \\\"./info-fragments/ICommonInfo.sol\\\";\\nimport \\\"./ICoinbaseExecution.sol\\\";\\nimport \\\"./ISlashingExecution.sol\\\";\\n\\ninterface IRoninValidatorSet is ICandidateManager, ICommonInfo, ISlashingExecution, ICoinbaseExecution {}\\n\",\"keccak256\":\"0x2475cf9c7007277ddfeade823196d0913a6d5c3e3fc9a1a10800734c0fdef062\",\"license\":\"MIT\"},\"contracts/interfaces/validator/ISlashingExecution.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface ISlashingExecution {\\n /// @dev Emitted when the validator is punished.\\n event ValidatorPunished(\\n address indexed consensusAddr,\\n uint256 indexed period,\\n uint256 jailedUntil,\\n uint256 deductedStakingAmount,\\n bool blockProducerRewardDeprecated,\\n bool bridgeOperatorRewardDeprecated\\n );\\n /// @dev Emitted when the validator get out of jail by bailout.\\n event ValidatorUnjailed(address indexed validator, uint256 period);\\n\\n /**\\n * @dev Finalize the slash request from slash indicator contract.\\n *\\n * Requirements:\\n * - The method caller is slash indicator contract.\\n *\\n * Emits the event `ValidatorPunished`.\\n *\\n */\\n function execSlash(\\n address _validatorAddr,\\n uint256 _newJailedUntil,\\n uint256 _slashAmount\\n ) external;\\n\\n /**\\n * @dev Finalize the bailout request from slash indicator contract.\\n *\\n * Requirements:\\n * - The method caller is slash indicator contract.\\n *\\n * Emits the event `ValidatorUnjailed`.\\n *\\n */\\n function execBailOut(address _validatorAddr, uint256 _period) external;\\n}\\n\",\"keccak256\":\"0xdeb929875d06c5dfb8562029ccc2922e1c5238f2dc67c8c61acad614f5fe1e28\",\"license\":\"MIT\"},\"contracts/interfaces/validator/info-fragments/ICommonInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"./IJailingInfo.sol\\\";\\nimport \\\"./ITimingInfo.sol\\\";\\nimport \\\"./IValidatorInfo.sol\\\";\\n\\ninterface ICommonInfo is ITimingInfo, IJailingInfo, IValidatorInfo {\\n /// @dev Emitted when the deprecated reward is withdrawn.\\n event DeprecatedRewardRecycled(address indexed recipientAddr, uint256 amount);\\n /// @dev Emitted when the deprecated reward withdrawal is failed\\n event DeprecatedRewardRecycleFailed(address indexed recipientAddr, uint256 amount, uint256 balance);\\n\\n /**\\n * @dev Returns the total deprecated reward, which includes reward that is not sent for slashed validators and unsastified bridge operators\\n */\\n function totalDeprecatedReward() external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x33a52025305948a8e71d32317e4cdb2cf779afc3bcdb5bcbd72df5e1513f449f\",\"license\":\"MIT\"},\"contracts/interfaces/validator/info-fragments/IJailingInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface IJailingInfo {\\n /**\\n * @dev Returns whether the validator are put in jail (cannot join the set of validators) during the current period.\\n */\\n function checkJailed(address) external view returns (bool);\\n\\n /**\\n * @dev Returns whether the validator are put in jail and the number of block and epoch that he still is in the jail.\\n */\\n function getJailedTimeLeft(address _addr)\\n external\\n view\\n returns (\\n bool isJailed_,\\n uint256 blockLeft_,\\n uint256 epochLeft_\\n );\\n\\n /**\\n * @dev Returns whether the validator are put in jail (cannot join the set of validators) at a specific block.\\n */\\n function checkJailedAtBlock(address _addr, uint256 _blockNum) external view returns (bool);\\n\\n /**\\n * @dev Returns whether the validator are put in jail at a specific block and the number of block and epoch that he still is in the jail.\\n */\\n function getJailedTimeLeftAtBlock(address _addr, uint256 _blockNum)\\n external\\n view\\n returns (\\n bool isJailed_,\\n uint256 blockLeft_,\\n uint256 epochLeft_\\n );\\n\\n /**\\n * @dev Returns whether the validators are put in jail (cannot join the set of validators) during the current period.\\n */\\n function checkManyJailed(address[] calldata) external view returns (bool[] memory);\\n\\n /**\\n * @dev Returns whether the incoming reward of the block producers are deprecated during the current period.\\n */\\n function checkMiningRewardDeprecated(address[] calldata _blockProducers) external view returns (bool[] memory);\\n\\n /**\\n * @dev Returns whether the incoming reward of the block producers are deprecated during a specific period.\\n */\\n function checkMiningRewardDeprecatedAtPeriod(address[] calldata _blockProducers, uint256 _period)\\n external\\n view\\n returns (bool[] memory);\\n}\\n\",\"keccak256\":\"0x310f321625fac8b7dbabfdad36e82b960b0b1f7bf0e5b70b763e45438b8a8d30\",\"license\":\"MIT\"},\"contracts/interfaces/validator/info-fragments/ITimingInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface ITimingInfo {\\n /**\\n * @dev Returns the block that validator set was updated.\\n */\\n function getLastUpdatedBlock() external view returns (uint256);\\n\\n /**\\n * @dev Returns the number of blocks in a epoch.\\n */\\n function numberOfBlocksInEpoch() external view returns (uint256 _numberOfBlocks);\\n\\n /**\\n * @dev Returns the epoch index from the block number.\\n */\\n function epochOf(uint256 _block) external view returns (uint256);\\n\\n /**\\n * @dev Returns whether the epoch ending is at the block number `_block`.\\n */\\n function epochEndingAt(uint256 _block) external view returns (bool);\\n\\n /**\\n * @dev Tries to get the period index from the epoch number.\\n */\\n function tryGetPeriodOfEpoch(uint256 _epoch) external view returns (bool _filled, uint256 _periodNumber);\\n\\n /**\\n * @dev Returns whether the period ending at the current block number.\\n */\\n function isPeriodEnding() external view returns (bool);\\n\\n /**\\n * @dev Returns the period index from the current block.\\n */\\n function currentPeriod() external view returns (uint256);\\n\\n /**\\n * @dev Returns the block number that the current period starts at.\\n */\\n function currentPeriodStartAtBlock() external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x77b86a68149389fed0eb0c5b8d56f278d3bd103ba64f504697d709b24c3212d5\",\"license\":\"MIT\"},\"contracts/interfaces/validator/info-fragments/IValidatorInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface IValidatorInfo {\\n /// @dev Emitted when the number of max validator is updated\\n event MaxValidatorNumberUpdated(uint256);\\n /// @dev Emitted when the number of reserved slots for prioritized validators is updated\\n event MaxPrioritizedValidatorNumberUpdated(uint256);\\n\\n /**\\n * @dev Returns the maximum number of validators in the epoch\\n */\\n function maxValidatorNumber() external view returns (uint256 _maximumValidatorNumber);\\n\\n /**\\n * @dev Returns the number of reserved slots for prioritized validators\\n */\\n function maxPrioritizedValidatorNumber() external view returns (uint256 _maximumPrioritizedValidatorNumber);\\n\\n /**\\n * @dev Returns the current validator list.\\n */\\n function getValidators() external view returns (address[] memory);\\n\\n /**\\n * @dev Returns whether the address is either a bridge operator or a block producer.\\n */\\n function isValidator(address _addr) external view returns (bool);\\n\\n /**\\n * @dev Returns the current block producer list.\\n */\\n function getBlockProducers() external view returns (address[] memory);\\n\\n /**\\n * @dev Returns whether the address is block producer or not.\\n */\\n function isBlockProducer(address _addr) external view returns (bool);\\n\\n /**\\n * @dev Returns total numbers of the block producers.\\n */\\n function totalBlockProducers() external view returns (uint256);\\n\\n /**\\n * @dev Returns the current bridge operator list.\\n */\\n function getBridgeOperators() external view returns (address[] memory);\\n\\n /**\\n * @dev Returns whether the address is bridge operator or not.\\n */\\n function isBridgeOperator(address _addr) external view returns (bool);\\n\\n /**\\n * @dev Returns total numbers of the bridge operators.\\n */\\n function totalBridgeOperators() external view returns (uint256);\\n\\n /**\\n * @dev Updates the max validator number\\n *\\n * Requirements:\\n * - The method caller is admin\\n *\\n * Emits the event `MaxValidatorNumberUpdated`\\n *\\n */\\n function setMaxValidatorNumber(uint256 _maxValidatorNumber) external;\\n\\n /**\\n * @dev Updates the number of reserved slots for prioritized validators\\n *\\n * Requirements:\\n * - The method caller is admin\\n *\\n * Emits the event `MaxPrioritizedValidatorNumberUpdated`\\n *\\n */\\n function setMaxPrioritizedValidatorNumber(uint256 _maxPrioritizedValidatorNumber) external;\\n}\\n\",\"keccak256\":\"0xf7f30bacc63b2e4e9548c83e45eac727eeafa46e60312f936bf189480e413323\",\"license\":\"MIT\"},\"contracts/libraries/AddressArrayUtils.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\n\\npragma solidity ^0.8.0;\\n\\nlibrary AddressArrayUtils {\\n /**\\n * Returns whether or not there's a duplicate. Runs in O(n^2).\\n * @param A Array to search\\n * @return Returns true if duplicate, false otherwise\\n */\\n function hasDuplicate(address[] memory A) internal pure returns (bool) {\\n if (A.length == 0) {\\n return false;\\n }\\n for (uint256 i = 0; i < A.length - 1; i++) {\\n for (uint256 j = i + 1; j < A.length; j++) {\\n if (A[i] == A[j]) {\\n return true;\\n }\\n }\\n }\\n return false;\\n }\\n}\\n\",\"keccak256\":\"0xc64f39980a5f980a3a87b3e4c692e0dd4848950a568cb5a24c39c6f99080c864\",\"license\":\"UNLICENSED\"},\"contracts/libraries/Math.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\n\\npragma solidity ^0.8.0;\\n\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns whether the number `c` is in range of [a; b].\\n */\\n function inRange(\\n uint256 c,\\n uint256 a,\\n uint256 b\\n ) internal pure returns (bool) {\\n return a <= c && c <= b;\\n }\\n\\n /**\\n * @dev Returns whether two inclusive ranges [x1;x2] and [y1;y2] overlap.\\n */\\n function twoRangeOverlap(\\n uint256 x1,\\n uint256 x2,\\n uint256 y1,\\n uint256 y2\\n ) internal pure returns (bool) {\\n return x1 <= y2 && y1 <= x2;\\n }\\n\\n /**\\n * @dev Returns value of a + b; in case result is larger than upperbound, upperbound is returned.\\n */\\n function addWithUpperbound(\\n uint256 a,\\n uint256 b,\\n uint256 upperbound\\n ) internal pure returns (uint256) {\\n return min(a + b, upperbound);\\n }\\n\\n /**\\n * @dev Returns value of a - b; in case of negative result, 0 is returned.\\n */\\n function subNonNegative(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a - min(a, b);\\n }\\n}\\n\",\"keccak256\":\"0xa9e2a3ad43d7999a3cdbfb040b0f2dec282eae91ff8fe6ad26fdd19087121ce7\",\"license\":\"UNLICENSED\"},\"contracts/ronin/staking/BaseStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport \\\"../../extensions/RONTransferHelper.sol\\\";\\nimport \\\"../../extensions/collections/HasValidatorContract.sol\\\";\\nimport \\\"../../interfaces/staking/IBaseStaking.sol\\\";\\nimport \\\"../../libraries/Math.sol\\\";\\nimport \\\"./RewardCalculation.sol\\\";\\n\\nabstract contract BaseStaking is\\n RONTransferHelper,\\n ReentrancyGuard,\\n RewardCalculation,\\n HasValidatorContract,\\n IBaseStaking\\n{\\n /// @dev Mapping from pool address => staking pool detail\\n mapping(address => PoolDetail) internal _stakingPool;\\n\\n /// @dev The cooldown time in seconds to undelegate from the last timestamp (s)he delegated.\\n uint256 internal _cooldownSecsToUndelegate;\\n /// @dev The number of seconds that a candidate must wait to be revoked and take the self-staking amount back.\\n uint256 internal _waitingSecsToRevoke;\\n\\n /// @dev Mapping from pool admin address => consensus address.\\n mapping(address => address) internal _activePoolAdminMapping;\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n */\\n uint256[49] private ______gap;\\n\\n modifier noEmptyValue() {\\n require(msg.value > 0, \\\"BaseStaking: query with empty value\\\");\\n _;\\n }\\n\\n modifier notPoolAdmin(PoolDetail storage _pool, address _delegator) {\\n require(_pool.admin != _delegator, \\\"BaseStaking: delegator must not be the pool admin\\\");\\n _;\\n }\\n\\n modifier onlyPoolAdmin(PoolDetail storage _pool, address _requester) {\\n require(_pool.admin == _requester, \\\"BaseStaking: requester must be the pool admin\\\");\\n _;\\n }\\n\\n modifier poolExists(address _poolAddr) {\\n require(_validatorContract.isValidatorCandidate(_poolAddr), \\\"BaseStaking: query for non-existent pool\\\");\\n _;\\n }\\n\\n /**\\n * @inheritdoc IBaseStaking\\n */\\n function isActivePoolAdmin(address _poolAdminAddr) public view override returns (bool) {\\n return _activePoolAdminMapping[_poolAdminAddr] != address(0);\\n }\\n\\n /**\\n * @inheritdoc IRewardPool\\n */\\n function getStakingTotal(address _poolAddr) public view override returns (uint256) {\\n return _stakingPool[_poolAddr].stakingTotal;\\n }\\n\\n /**\\n * @inheritdoc IRewardPool\\n */\\n function getManyStakingTotals(address[] calldata _poolList)\\n public\\n view\\n override\\n returns (uint256[] memory _stakingAmounts)\\n {\\n _stakingAmounts = new uint256[](_poolList.length);\\n for (uint _i = 0; _i < _poolList.length; _i++) {\\n _stakingAmounts[_i] = getStakingTotal(_poolList[_i]);\\n }\\n }\\n\\n /**\\n * @inheritdoc IRewardPool\\n */\\n function getStakingAmount(address _poolAddr, address _user) public view override returns (uint256) {\\n return _stakingPool[_poolAddr].delegatingAmount[_user];\\n }\\n\\n /**\\n * @inheritdoc IRewardPool\\n */\\n function getManyStakingAmounts(address[] calldata _poolAddrs, address[] calldata _userList)\\n external\\n view\\n override\\n returns (uint256[] memory _stakingAmounts)\\n {\\n require(_poolAddrs.length == _userList.length, \\\"BaseStaking: invalid input array\\\");\\n _stakingAmounts = new uint256[](_poolAddrs.length);\\n for (uint _i = 0; _i < _stakingAmounts.length; _i++) {\\n _stakingAmounts[_i] = _stakingPool[_poolAddrs[_i]].delegatingAmount[_userList[_i]];\\n }\\n }\\n\\n /**\\n * @inheritdoc IBaseStaking\\n */\\n function cooldownSecsToUndelegate() external view returns (uint256) {\\n return _cooldownSecsToUndelegate;\\n }\\n\\n /**\\n * @inheritdoc IBaseStaking\\n */\\n function waitingSecsToRevoke() external view returns (uint256) {\\n return _waitingSecsToRevoke;\\n }\\n\\n /**\\n * @inheritdoc IBaseStaking\\n */\\n function setCooldownSecsToUndelegate(uint256 _cooldownSecs) external override onlyAdmin {\\n _setCooldownSecsToUndelegate(_cooldownSecs);\\n }\\n\\n /**\\n * @inheritdoc IBaseStaking\\n */\\n function setWaitingSecsToRevoke(uint256 _secs) external override onlyAdmin {\\n _setWaitingSecsToRevoke(_secs);\\n }\\n\\n /**\\n * @dev Sets the minium number of seconds to undelegate.\\n *\\n * Emits the event `CooldownSecsToUndelegateUpdated`.\\n *\\n */\\n function _setCooldownSecsToUndelegate(uint256 _cooldownSecs) internal {\\n _cooldownSecsToUndelegate = _cooldownSecs;\\n emit CooldownSecsToUndelegateUpdated(_cooldownSecs);\\n }\\n\\n /**\\n * @dev Sets the number of seconds that a candidate must wait to be revoked.\\n *\\n * Emits the event `WaitingSecsToRevokeUpdated`.\\n *\\n */\\n function _setWaitingSecsToRevoke(uint256 _secs) internal {\\n _waitingSecsToRevoke = _secs;\\n emit WaitingSecsToRevokeUpdated(_secs);\\n }\\n\\n /**\\n * @dev Changes the delegate amount.\\n */\\n function _changeDelegatingAmount(\\n PoolDetail storage _pool,\\n address _delegator,\\n uint256 _newDelegatingAmount,\\n uint256 _newStakingTotal\\n ) internal {\\n _syncUserReward(_pool.addr, _delegator, _newDelegatingAmount);\\n _pool.stakingTotal = _newStakingTotal;\\n _pool.delegatingAmount[_delegator] = _newDelegatingAmount;\\n }\\n}\\n\",\"keccak256\":\"0x30a983ca66e6bc5a080164c8e072e304d04f855d42a1f3dc5e731da11e95cdd5\",\"license\":\"MIT\"},\"contracts/ronin/staking/CandidateStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"../../libraries/AddressArrayUtils.sol\\\";\\nimport \\\"../../interfaces/staking/ICandidateStaking.sol\\\";\\nimport \\\"./BaseStaking.sol\\\";\\n\\nabstract contract CandidateStaking is BaseStaking, ICandidateStaking {\\n /// @dev The minimum threshold for being a validator candidate.\\n uint256 internal _minValidatorStakingAmount;\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n */\\n uint256[50] private ______gap;\\n\\n /**\\n * @inheritdoc ICandidateStaking\\n */\\n function minValidatorStakingAmount() public view override returns (uint256) {\\n return _minValidatorStakingAmount;\\n }\\n\\n /**\\n * @inheritdoc ICandidateStaking\\n */\\n function setMinValidatorStakingAmount(uint256 _threshold) external override onlyAdmin {\\n _setMinValidatorStakingAmount(_threshold);\\n }\\n\\n /**\\n * @inheritdoc ICandidateStaking\\n */\\n function applyValidatorCandidate(\\n address _candidateAdmin,\\n address _consensusAddr,\\n address payable _treasuryAddr,\\n address _bridgeOperatorAddr,\\n uint256 _commissionRate\\n ) external payable override nonReentrant {\\n require(!isActivePoolAdmin(msg.sender), \\\"CandidateStaking: pool admin is active\\\");\\n\\n uint256 _amount = msg.value;\\n address payable _poolAdmin = payable(msg.sender);\\n _applyValidatorCandidate(\\n _poolAdmin,\\n _candidateAdmin,\\n _consensusAddr,\\n _treasuryAddr,\\n _bridgeOperatorAddr,\\n _commissionRate,\\n _amount\\n );\\n\\n PoolDetail storage _pool = _stakingPool[_consensusAddr];\\n _pool.admin = _poolAdmin;\\n _pool.addr = _consensusAddr;\\n _activePoolAdminMapping[_poolAdmin] = _consensusAddr;\\n\\n _stake(_stakingPool[_consensusAddr], _poolAdmin, _amount);\\n emit PoolApproved(_consensusAddr, _poolAdmin);\\n }\\n\\n /**\\n * @inheritdoc ICandidateStaking\\n */\\n function requestUpdateCommissionRate(\\n address _consensusAddr,\\n uint256 _effectiveDaysOnwards,\\n uint256 _commissionRate\\n ) external override poolExists(_consensusAddr) onlyPoolAdmin(_stakingPool[_consensusAddr], msg.sender) {\\n _validatorContract.execRequestUpdateCommissionRate(_consensusAddr, _effectiveDaysOnwards, _commissionRate);\\n }\\n\\n /**\\n * @inheritdoc ICandidateStaking\\n */\\n function deprecatePools(address[] calldata _pools) external override onlyValidatorContract {\\n if (_pools.length == 0) {\\n return;\\n }\\n\\n uint256 _amount;\\n for (uint _i = 0; _i < _pools.length; _i++) {\\n PoolDetail storage _pool = _stakingPool[_pools[_i]];\\n // Deactivate the pool admin in the active mapping.\\n delete _activePoolAdminMapping[_pool.admin];\\n\\n // Deduct and transfer the self staking amount to the pool admin.\\n _amount = _pool.stakingAmount;\\n if (_amount > 0) {\\n _deductStakingAmount(_pool, _amount);\\n if (!_unsafeSendRON(payable(_pool.admin), _amount)) {\\n emit StakingAmountTransferFailed(_pool.addr, _pool.admin, _amount, address(this).balance);\\n }\\n }\\n }\\n\\n emit PoolsDeprecated(_pools);\\n }\\n\\n /**\\n * @inheritdoc ICandidateStaking\\n */\\n function stake(address _consensusAddr) external payable override noEmptyValue poolExists(_consensusAddr) {\\n _stake(_stakingPool[_consensusAddr], msg.sender, msg.value);\\n }\\n\\n /**\\n * @inheritdoc ICandidateStaking\\n */\\n function unstake(address _consensusAddr, uint256 _amount) external override nonReentrant poolExists(_consensusAddr) {\\n require(_amount > 0, \\\"CandidateStaking: invalid amount\\\");\\n address _delegator = msg.sender;\\n PoolDetail storage _pool = _stakingPool[_consensusAddr];\\n uint256 _remainAmount = _pool.stakingAmount - _amount;\\n require(_remainAmount >= _minValidatorStakingAmount, \\\"CandidateStaking: invalid staking amount left\\\");\\n\\n _unstake(_pool, _delegator, _amount);\\n require(_sendRON(payable(_delegator), _amount), \\\"CandidateStaking: could not transfer RON\\\");\\n }\\n\\n /**\\n * @inheritdoc ICandidateStaking\\n */\\n function requestRenounce(address _consensusAddr)\\n external\\n override\\n poolExists(_consensusAddr)\\n onlyPoolAdmin(_stakingPool[_consensusAddr], msg.sender)\\n {\\n _validatorContract.requestRevokeCandidate(_consensusAddr, _waitingSecsToRevoke);\\n }\\n\\n /**\\n * @dev See `ICandidateStaking-applyValidatorCandidate`\\n */\\n function _applyValidatorCandidate(\\n address payable _poolAdmin,\\n address _candidateAdmin,\\n address _consensusAddr,\\n address payable _treasuryAddr,\\n address _bridgeOperatorAddr,\\n uint256 _commissionRate,\\n uint256 _amount\\n ) internal {\\n require(_sendRON(_poolAdmin, 0), \\\"CandidateStaking: pool admin cannot receive RON\\\");\\n require(_sendRON(_treasuryAddr, 0), \\\"CandidateStaking: treasury cannot receive RON\\\");\\n require(_amount >= _minValidatorStakingAmount, \\\"CandidateStaking: insufficient amount\\\");\\n\\n require(\\n _poolAdmin == _candidateAdmin && _candidateAdmin == _treasuryAddr,\\n \\\"CandidateStaking: three interaction addresses must be of the same\\\"\\n );\\n\\n address[] memory _diffAddrs = new address[](3);\\n _diffAddrs[0] = _poolAdmin;\\n _diffAddrs[1] = _consensusAddr;\\n _diffAddrs[2] = _bridgeOperatorAddr;\\n require(\\n !AddressArrayUtils.hasDuplicate(_diffAddrs),\\n \\\"CandidateStaking: three operation addresses must be distinct\\\"\\n );\\n\\n _validatorContract.grantValidatorCandidate(\\n _candidateAdmin,\\n _consensusAddr,\\n _treasuryAddr,\\n _bridgeOperatorAddr,\\n _commissionRate\\n );\\n }\\n\\n /**\\n * @dev See `ICandidateStaking-stake`\\n */\\n function _stake(\\n PoolDetail storage _pool,\\n address _requester,\\n uint256 _amount\\n ) internal onlyPoolAdmin(_pool, _requester) {\\n _pool.stakingAmount += _amount;\\n _changeDelegatingAmount(_pool, _requester, _pool.stakingAmount, _pool.stakingTotal + _amount);\\n _pool.lastDelegatingTimestamp[_requester] = block.timestamp;\\n emit Staked(_pool.addr, _amount);\\n }\\n\\n /**\\n * @dev See `ICandidateStaking-unstake`\\n */\\n function _unstake(\\n PoolDetail storage _pool,\\n address _requester,\\n uint256 _amount\\n ) internal onlyPoolAdmin(_pool, _requester) {\\n require(_amount <= _pool.stakingAmount, \\\"CandidateStaking: insufficient staking amount\\\");\\n require(\\n _pool.lastDelegatingTimestamp[_requester] + _cooldownSecsToUndelegate <= block.timestamp,\\n \\\"CandidateStaking: unstake too early\\\"\\n );\\n\\n _pool.stakingAmount -= _amount;\\n _changeDelegatingAmount(_pool, _requester, _pool.stakingAmount, _pool.stakingTotal - _amount);\\n emit Unstaked(_pool.addr, _amount);\\n }\\n\\n /**\\n * @dev Deducts from staking amount of the validator `_consensusAddr` for `_amount`.\\n *\\n * Emits the event `Unstaked`.\\n *\\n * @return The actual deducted amount\\n */\\n function _deductStakingAmount(PoolDetail storage _pool, uint256 _amount) internal virtual returns (uint256);\\n\\n /**\\n * @dev Sets the minimum threshold for being a validator candidate.\\n *\\n * Emits the `MinValidatorStakingAmountUpdated` event.\\n *\\n */\\n function _setMinValidatorStakingAmount(uint256 _threshold) internal {\\n _minValidatorStakingAmount = _threshold;\\n emit MinValidatorStakingAmountUpdated(_threshold);\\n }\\n}\\n\",\"keccak256\":\"0xe80c374e9425772e3a50721371b108148b325bef59536e9ce7ca963f81d49f7e\",\"license\":\"MIT\"},\"contracts/ronin/staking/DelegatorStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"../../interfaces/staking/IDelegatorStaking.sol\\\";\\nimport \\\"./BaseStaking.sol\\\";\\n\\nabstract contract DelegatorStaking is BaseStaking, IDelegatorStaking {\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n */\\n uint256[50] private ______gap;\\n\\n /**\\n * @inheritdoc IDelegatorStaking\\n */\\n function delegate(address _consensusAddr) external payable noEmptyValue poolExists(_consensusAddr) {\\n require(!isActivePoolAdmin(msg.sender), \\\"DelegatorStaking: admin of an active pool cannot delegate\\\");\\n _delegate(_stakingPool[_consensusAddr], msg.sender, msg.value);\\n }\\n\\n /**\\n * @inheritdoc IDelegatorStaking\\n */\\n function undelegate(address _consensusAddr, uint256 _amount) external nonReentrant {\\n address payable _delegator = payable(msg.sender);\\n _undelegate(_stakingPool[_consensusAddr], _delegator, _amount);\\n require(_sendRON(_delegator, _amount), \\\"DelegatorStaking: could not transfer RON\\\");\\n }\\n\\n /**\\n * @inheritdoc IDelegatorStaking\\n */\\n function bulkUndelegate(address[] calldata _consensusAddrs, uint256[] calldata _amounts) external nonReentrant {\\n require(\\n _consensusAddrs.length > 0 && _consensusAddrs.length == _amounts.length,\\n \\\"DelegatorStaking: invalid array length\\\"\\n );\\n\\n address payable _delegator = payable(msg.sender);\\n uint256 _total;\\n\\n for (uint _i = 0; _i < _consensusAddrs.length; _i++) {\\n _total += _amounts[_i];\\n _undelegate(_stakingPool[_consensusAddrs[_i]], _delegator, _amounts[_i]);\\n }\\n\\n require(_sendRON(_delegator, _total), \\\"DelegatorStaking: could not transfer RON\\\");\\n }\\n\\n /**\\n * @inheritdoc IDelegatorStaking\\n */\\n function redelegate(\\n address _consensusAddrSrc,\\n address _consensusAddrDst,\\n uint256 _amount\\n ) external nonReentrant poolExists(_consensusAddrDst) {\\n address _delegator = msg.sender;\\n _undelegate(_stakingPool[_consensusAddrSrc], _delegator, _amount);\\n _delegate(_stakingPool[_consensusAddrDst], _delegator, _amount);\\n }\\n\\n /**\\n * @inheritdoc IDelegatorStaking\\n */\\n function claimRewards(address[] calldata _consensusAddrList)\\n external\\n override\\n nonReentrant\\n returns (uint256 _amount)\\n {\\n _amount = _claimRewards(msg.sender, _consensusAddrList);\\n _transferRON(payable(msg.sender), _amount);\\n }\\n\\n /**\\n * @inheritdoc IDelegatorStaking\\n */\\n function delegateRewards(address[] calldata _consensusAddrList, address _consensusAddrDst)\\n external\\n override\\n nonReentrant\\n poolExists(_consensusAddrDst)\\n returns (uint256 _amount)\\n {\\n return _delegateRewards(msg.sender, _consensusAddrList, _consensusAddrDst);\\n }\\n\\n /**\\n * @inheritdoc IDelegatorStaking\\n */\\n function getRewards(address _user, address[] calldata _poolAddrList)\\n external\\n view\\n returns (uint256[] memory _rewards)\\n {\\n address _consensusAddr;\\n uint256 _period = _validatorContract.currentPeriod();\\n _rewards = new uint256[](_poolAddrList.length);\\n\\n for (uint256 _i = 0; _i < _poolAddrList.length; _i++) {\\n _consensusAddr = _poolAddrList[_i];\\n _rewards[_i] = _getReward(_consensusAddr, _user, _period, getStakingAmount(_consensusAddr, _user));\\n }\\n }\\n\\n /**\\n * @dev Delegates from a validator address.\\n *\\n * Requirements:\\n * - The delegator is not the pool admin.\\n *\\n * Emits the `Delegated` event.\\n *\\n * Note: This function does not verify the `msg.value` with the amount.\\n *\\n */\\n function _delegate(\\n PoolDetail storage _pool,\\n address _delegator,\\n uint256 _amount\\n ) internal notPoolAdmin(_pool, _delegator) {\\n _changeDelegatingAmount(\\n _pool,\\n _delegator,\\n _pool.delegatingAmount[_delegator] + _amount,\\n _pool.stakingTotal + _amount\\n );\\n _pool.lastDelegatingTimestamp[_delegator] = block.timestamp;\\n emit Delegated(_delegator, _pool.addr, _amount);\\n }\\n\\n /**\\n * @dev Undelegates from a validator address.\\n *\\n * Requirements:\\n * - The delegator is not the pool admin.\\n * - The amount is larger than 0.\\n * - The delegating amount is larger than or equal to the undelegating amount.\\n *\\n * Emits the `Undelegated` event.\\n *\\n * Note: Consider transferring back the amount of RON after calling this function.\\n *\\n */\\n function _undelegate(\\n PoolDetail storage _pool,\\n address _delegator,\\n uint256 _amount\\n ) private notPoolAdmin(_pool, _delegator) {\\n require(_amount > 0, \\\"DelegatorStaking: invalid amount\\\");\\n require(_pool.delegatingAmount[_delegator] >= _amount, \\\"DelegatorStaking: insufficient amount to undelegate\\\");\\n require(\\n _pool.lastDelegatingTimestamp[_delegator] + _cooldownSecsToUndelegate < block.timestamp,\\n \\\"DelegatorStaking: undelegate too early\\\"\\n );\\n _changeDelegatingAmount(\\n _pool,\\n _delegator,\\n _pool.delegatingAmount[_delegator] - _amount,\\n _pool.stakingTotal - _amount\\n );\\n emit Undelegated(_delegator, _pool.addr, _amount);\\n }\\n\\n /**\\n * @dev Claims rewards from the pools `_poolAddrList`.\\n * Note: This function does not transfer reward to user.\\n */\\n function _claimRewards(address _user, address[] calldata _poolAddrList) internal returns (uint256 _amount) {\\n for (uint256 _i = 0; _i < _poolAddrList.length; _i++) {\\n _amount += _claimReward(_poolAddrList[_i], _user);\\n }\\n }\\n\\n /**\\n * @dev Claims the rewards and delegates them to the consensus address.\\n */\\n function _delegateRewards(\\n address _user,\\n address[] calldata _poolAddrList,\\n address _poolAddrDst\\n ) internal returns (uint256 _amount) {\\n _amount = _claimRewards(_user, _poolAddrList);\\n _delegate(_stakingPool[_poolAddrDst], _user, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xf398428c3d6123e20f0f05c6d0ccaaea6f3e6366a52a66620c82b77954ce66ad\",\"license\":\"MIT\"},\"contracts/ronin/staking/RewardCalculation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"../../interfaces/staking/IRewardPool.sol\\\";\\nimport \\\"../../libraries/Math.sol\\\";\\n\\n/**\\n * @title RewardCalculation contract\\n * @dev This contract mainly contains the methods to calculate reward for staking contract.\\n */\\nabstract contract RewardCalculation is IRewardPool {\\n /// @dev Mapping from pool address => period number => accumulated rewards per share (one unit staking)\\n mapping(address => mapping(uint256 => PeriodWrapper)) private _accumulatedRps;\\n /// @dev Mapping from the pool address => user address => the reward info of the user\\n mapping(address => mapping(address => UserRewardFields)) private _userReward;\\n /// @dev Mapping from the pool address => reward pool fields\\n mapping(address => PoolFields) private _stakingPool;\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n */\\n uint256[50] private ______gap;\\n\\n /**\\n * @inheritdoc IRewardPool\\n */\\n function getReward(address _poolAddr, address _user) external view returns (uint256) {\\n return _getReward(_poolAddr, _user, _currentPeriod(), getStakingAmount(_poolAddr, _user));\\n }\\n\\n /**\\n * @inheritdoc IRewardPool\\n */\\n function getStakingAmount(address _poolAddr, address _user) public view virtual returns (uint256);\\n\\n /**\\n * @inheritdoc IRewardPool\\n */\\n function getStakingTotal(address _poolAddr) public view virtual returns (uint256);\\n\\n /**\\n * @dev Returns the reward amount that user claimable.\\n */\\n function _getReward(\\n address _poolAddr,\\n address _user,\\n uint256 _latestPeriod,\\n uint256 _latestStakingAmount\\n ) internal view returns (uint256) {\\n UserRewardFields storage _reward = _userReward[_poolAddr][_user];\\n\\n if (_reward.lastPeriod == _latestPeriod) {\\n return _reward.debited;\\n }\\n\\n uint256 _aRps;\\n uint256 _lastPeriodReward;\\n PoolFields storage _pool = _stakingPool[_poolAddr];\\n PeriodWrapper storage _wrappedArps = _accumulatedRps[_poolAddr][_reward.lastPeriod];\\n\\n if (_wrappedArps.lastPeriod > 0) {\\n // Calculates the last period reward if the aRps at the period is set\\n _aRps = _accumulatedRps[_poolAddr][_reward.lastPeriod].inner;\\n _lastPeriodReward = _reward.minAmount * (_aRps - _reward.aRps);\\n } else {\\n // Fallbacks to the previous aRps in case the aRps is not set\\n _aRps = _reward.aRps;\\n }\\n\\n uint256 _newPeriodsReward = _latestStakingAmount * (_pool.aRps - _aRps);\\n return _reward.debited + (_lastPeriodReward + _newPeriodsReward) / 1e18;\\n }\\n\\n /**\\n * @dev Syncs the user reward.\\n *\\n * Emits the event `UserRewardUpdated` once the debit amount is updated.\\n * Emits the event `PoolSharesUpdated` once the pool share is updated.\\n *\\n * Note: The method should be called whenever the user's staking amount changes.\\n *\\n */\\n function _syncUserReward(\\n address _poolAddr,\\n address _user,\\n uint256 _newStakingAmount\\n ) internal {\\n uint256 _period = _currentPeriod();\\n PoolFields storage _pool = _stakingPool[_poolAddr];\\n uint256 _lastShares = _pool.shares.inner;\\n\\n // Updates the pool shares if it is outdated\\n if (_pool.shares.lastPeriod < _period) {\\n _pool.shares = PeriodWrapper(getStakingTotal(_poolAddr), _period);\\n }\\n\\n UserRewardFields storage _reward = _userReward[_poolAddr][_user];\\n uint256 _currentStakingAmount = getStakingAmount(_poolAddr, _user);\\n uint256 _debited = _getReward(_poolAddr, _user, _period, _currentStakingAmount);\\n\\n if (_reward.debited != _debited) {\\n _reward.debited = _debited;\\n emit UserRewardUpdated(_poolAddr, _user, _debited);\\n }\\n\\n _syncMinStakingAmount(_pool, _reward, _period, _newStakingAmount, _currentStakingAmount);\\n _reward.aRps = _pool.aRps;\\n _reward.lastPeriod = _period;\\n\\n if (_pool.shares.inner != _lastShares) {\\n emit PoolSharesUpdated(_period, _poolAddr, _pool.shares.inner);\\n }\\n }\\n\\n /**\\n * @dev Syncs the minimum staking amount of an user in the current period.\\n */\\n function _syncMinStakingAmount(\\n PoolFields storage _pool,\\n UserRewardFields storage _reward,\\n uint256 _latestPeriod,\\n uint256 _newStakingAmount,\\n uint256 _currentStakingAmount\\n ) internal {\\n if (_reward.lastPeriod < _latestPeriod) {\\n _reward.minAmount = _currentStakingAmount;\\n }\\n\\n uint256 _minAmount = Math.min(_reward.minAmount, _newStakingAmount);\\n uint256 _diffAmount = _reward.minAmount - _minAmount;\\n if (_diffAmount > 0) {\\n _reward.minAmount = _minAmount;\\n require(_pool.shares.inner >= _diffAmount, \\\"RewardCalculation: invalid pool shares\\\");\\n _pool.shares.inner -= _diffAmount;\\n }\\n }\\n\\n /**\\n * @dev Claims the settled reward for a specific user.\\n *\\n * Emits the `PendingRewardUpdated` event and the `SettledRewardUpdated` event.\\n *\\n * Note: This method should be called before transferring rewards for the user.\\n *\\n */\\n function _claimReward(address _poolAddr, address _user) internal returns (uint256 _amount) {\\n uint256 _latestPeriod = _currentPeriod();\\n _amount = _getReward(_poolAddr, _user, _latestPeriod, getStakingAmount(_poolAddr, _user));\\n emit RewardClaimed(_poolAddr, _user, _amount);\\n\\n UserRewardFields storage _reward = _userReward[_poolAddr][_user];\\n _reward.debited = 0;\\n _reward.lastPeriod = _latestPeriod;\\n _reward.aRps = _stakingPool[_poolAddr].aRps;\\n emit UserRewardUpdated(_poolAddr, _user, 0);\\n }\\n\\n /**\\n * @dev Records the amount of rewards `_rewards` for the pools `_poolAddrs`.\\n *\\n * Emits the event `PoolsUpdated` once the contract recorded the rewards successfully.\\n * Emits the event `PoolsUpdateFailed` once the input array lengths are not equal.\\n * Emits the event `PoolUpdateConflicted` when the pool is already updated in the period.\\n *\\n * Note: This method should be called once at the period ending.\\n *\\n */\\n function _recordRewards(\\n address[] memory _poolAddrs,\\n uint256[] calldata _rewards,\\n uint256 _period\\n ) internal {\\n if (_poolAddrs.length != _rewards.length) {\\n emit PoolsUpdateFailed(_period, _poolAddrs, _rewards);\\n return;\\n }\\n\\n uint256 _rps;\\n uint256 _count;\\n address _poolAddr;\\n uint256 _stakingTotal;\\n uint256[] memory _aRps = new uint256[](_poolAddrs.length);\\n uint256[] memory _shares = new uint256[](_poolAddrs.length);\\n address[] memory _conflicted = new address[](_poolAddrs.length);\\n\\n for (uint _i = 0; _i < _poolAddrs.length; _i++) {\\n _poolAddr = _poolAddrs[_i];\\n PoolFields storage _pool = _stakingPool[_poolAddr];\\n _stakingTotal = getStakingTotal(_poolAddr);\\n\\n if (_accumulatedRps[_poolAddr][_period].lastPeriod == _period) {\\n _conflicted[_count++] = _poolAddr;\\n continue;\\n }\\n\\n // Updates the pool shares if it is outdated\\n if (_pool.shares.lastPeriod < _period) {\\n _pool.shares = PeriodWrapper(_stakingTotal, _period);\\n }\\n\\n // The rps is 0 if no one stakes for the pool\\n _rps = _pool.shares.inner == 0 ? 0 : (_rewards[_i] * 1e18) / _pool.shares.inner;\\n _aRps[_i - _count] = _pool.aRps += _rps;\\n _accumulatedRps[_poolAddr][_period] = PeriodWrapper(_pool.aRps, _period);\\n if (_pool.shares.inner != _stakingTotal) {\\n _pool.shares.inner = _stakingTotal;\\n }\\n _shares[_i - _count] = _pool.shares.inner;\\n _poolAddrs[_i - _count] = _poolAddr;\\n }\\n\\n if (_count > 0) {\\n assembly {\\n mstore(_conflicted, _count)\\n mstore(_poolAddrs, sub(mload(_poolAddrs), _count))\\n }\\n emit PoolsUpdateConflicted(_period, _conflicted);\\n }\\n\\n if (_poolAddrs.length > 0) {\\n emit PoolsUpdated(_period, _poolAddrs, _aRps, _shares);\\n }\\n }\\n\\n /**\\n * @dev Returns the current period.\\n */\\n function _currentPeriod() internal view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0x43d7da0f22746bda6a2878f9ab10556a26910756b6ac26a58ec8221e3f09637f\",\"license\":\"MIT\"},\"contracts/ronin/staking/Staking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"@openzeppelin/contracts/proxy/utils/Initializable.sol\\\";\\nimport \\\"../../interfaces/staking/IStaking.sol\\\";\\nimport \\\"../../interfaces/validator/IRoninValidatorSet.sol\\\";\\nimport \\\"./CandidateStaking.sol\\\";\\nimport \\\"./DelegatorStaking.sol\\\";\\n\\ncontract Staking is IStaking, CandidateStaking, DelegatorStaking, Initializable {\\n constructor() {\\n _disableInitializers();\\n }\\n\\n receive() external payable onlyValidatorContract {}\\n\\n fallback() external payable onlyValidatorContract {}\\n\\n /**\\n * @dev Initializes the contract storage.\\n */\\n function initialize(\\n address __validatorContract,\\n uint256 __minValidatorStakingAmount,\\n uint256 __cooldownSecsToUndelegate,\\n uint256 __waitingSecsToRevoke\\n ) external initializer {\\n _setValidatorContract(__validatorContract);\\n _setMinValidatorStakingAmount(__minValidatorStakingAmount);\\n _setCooldownSecsToUndelegate(__cooldownSecsToUndelegate);\\n _setWaitingSecsToRevoke(__waitingSecsToRevoke);\\n }\\n\\n /**\\n * @inheritdoc IStaking\\n */\\n function getStakingPool(address _poolAddr)\\n external\\n view\\n poolExists(_poolAddr)\\n returns (\\n address _admin,\\n uint256 _stakingAmount,\\n uint256 _stakingTotal\\n )\\n {\\n PoolDetail storage _pool = _stakingPool[_poolAddr];\\n return (_pool.admin, _pool.stakingAmount, _pool.stakingTotal);\\n }\\n\\n /**\\n * @inheritdoc IStaking\\n */\\n function getManySelfStakings(address[] calldata _pools) external view returns (uint256[] memory _selfStakings) {\\n _selfStakings = new uint256[](_pools.length);\\n for (uint _i = 0; _i < _pools.length; _i++) {\\n _selfStakings[_i] = _stakingPool[_pools[_i]].stakingAmount;\\n }\\n }\\n\\n /**\\n * @inheritdoc IStaking\\n */\\n function recordRewards(\\n address[] calldata _consensusAddrs,\\n uint256[] calldata _rewards,\\n uint256 _period\\n ) external payable onlyValidatorContract {\\n _recordRewards(_consensusAddrs, _rewards, _period);\\n }\\n\\n /**\\n * @inheritdoc IStaking\\n */\\n function deductStakingAmount(address _consensusAddr, uint256 _amount)\\n external\\n onlyValidatorContract\\n returns (uint256 _actualDeductingAmount)\\n {\\n _actualDeductingAmount = _deductStakingAmount(_stakingPool[_consensusAddr], _amount);\\n address payable _recipientAddr = payable(validatorContract());\\n if (!_unsafeSendRON(_recipientAddr, _actualDeductingAmount)) {\\n emit StakingAmountDeductFailed(_consensusAddr, _recipientAddr, _actualDeductingAmount, address(this).balance);\\n }\\n }\\n\\n /**\\n * @inheritdoc RewardCalculation\\n */\\n function _currentPeriod() internal view virtual override returns (uint256) {\\n return _validatorContract.currentPeriod();\\n }\\n\\n /**\\n * @inheritdoc CandidateStaking\\n */\\n function _deductStakingAmount(PoolDetail storage _pool, uint256 _amount)\\n internal\\n override\\n returns (uint256 _actualDeductingAmount)\\n {\\n _actualDeductingAmount = Math.min(_pool.stakingAmount, _amount);\\n\\n _pool.stakingAmount -= _actualDeductingAmount;\\n _changeDelegatingAmount(_pool, _pool.admin, _pool.stakingAmount, _pool.stakingTotal - _actualDeductingAmount);\\n emit Unstaked(_pool.addr, _actualDeductingAmount);\\n }\\n}\\n\",\"keccak256\":\"0x904e300370b0fdc65a42a587097a77a284a270732abee90a5848a15ef716acfd\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b5060016000556200002162000027565b620000e9565b60d154610100900460ff1615620000945760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60d15460ff9081161015620000e75760d1805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b613cef80620000f96000396000f3fe6080604052600436106101e75760003560e01c8063895ab74211610102578063af24542911610095578063e115877b11610064578063e115877b146105dd578063e5376f5414610628578063e9ac5e061461063b578063f9f031df1461065b57610230565b8063af24542914610568578063c2a672e01461057d578063c905bb351461059d578063cdf64a76146105bd57610230565b80639488e4e9116100d15780639488e4e9146104bb578063969ffc14146104db57806399439089146104fb5780639e614e0e1461052357610230565b8063895ab7421461042d578063909791dd1461046657806391f8723f1461047b578063924f081e1461049b57610230565b80634d99dd161161017a5780636b091695116101495780636b091695146103ad5780636bd8f804146103cd57806376664b65146103ed578063888b9ae91461040d57610230565b80634d99dd161461033a5780634ec81af11461035a5780635c19a95c1461037a578063679a6e431461038d57610230565b806326476204116101b657806326476204146102d45780633b8cb16b146102e75780633d8e846e146102fa57806342ef3c341461031a57610230565b80630682e8fa14610243578063095f647514610267578063097e4a9d146102945780631658c86e146102b457610230565b3661023057336101ff6036546001600160a01b031690565b6001600160a01b03161461022e5760405162461bcd60e51b815260040161022590613428565b60405180910390fd5b005b336101ff6036546001600160a01b031690565b34801561024f57600080fd5b506038545b6040519081526020015b60405180910390f35b34801561027357600080fd5b506102876102823660046134d0565b61067b565b60405161025e9190613576565b3480156102a057600080fd5b506102546102af36600461359e565b6107ec565b3480156102c057600080fd5b5061022e6102cf3660046135f4565b6108b9565b61022e6102e23660046135f4565b6109f3565b61022e6102f5366004613618565b610ac4565b34801561030657600080fd5b5061028761031536600461368b565b610b45565b34801561032657600080fd5b506102876103353660046136df565b610c89565b34801561034657600080fd5b5061022e610355366004613720565b610d5f565b34801561036657600080fd5b5061022e61037536600461374c565b610dda565b61022e6103883660046135f4565b610f0a565b34801561039957600080fd5b5061022e6103a8366004613787565b611063565b3480156103b957600080fd5b506102546103c83660046137a0565b6110a7565b3480156103d957600080fd5b5061022e6103e83660046137d9565b6110c9565b3480156103f957600080fd5b506102546104083660046137a0565b6111ce565b34801561041957600080fd5b5061022e610428366004613787565b6111fd565b34801561043957600080fd5b506102546104483660046135f4565b6001600160a01b031660009081526037602052604090206003015490565b34801561047257600080fd5b50606c54610254565b34801561048757600080fd5b506102876104963660046136df565b61123e565b3480156104a757600080fd5b5061022e6104b636600461381a565b6112e8565b3480156104c757600080fd5b5061022e6104d63660046134d0565b611428565b3480156104e757600080fd5b5061022e6104f6366004613787565b61159e565b34801561050757600080fd5b506036546040516001600160a01b03909116815260200161025e565b34801561052f57600080fd5b5061054361053e3660046135f4565b6115df565b604080516001600160a01b03909416845260208401929092529082015260600161025e565b34801561057457600080fd5b50603954610254565b34801561058957600080fd5b5061022e610598366004613720565b6116a5565b3480156105a957600080fd5b506102546105b8366004613720565b6118ad565b3480156105c957600080fd5b5061022e6105d83660046135f4565b61197f565b3480156105e957600080fd5b506106186105f83660046135f4565b6001600160a01b039081166000908152603a602052604090205416151590565b604051901515815260200161025e565b61022e61063636600461384f565b611a2c565b34801561064757600080fd5b5061022e6106563660046136df565b611b89565b34801561066757600080fd5b506102546106763660046136df565b611d18565b60608382146106cc5760405162461bcd60e51b815260206004820181905260248201527f426173655374616b696e673a20696e76616c696420696e7075742061727261796044820152606401610225565b836001600160401b038111156106e4576106e46138b3565b60405190808252806020026020018201604052801561070d578160200160208202803683370190505b50905060005b81518110156107e35760376000878784818110610732576107326138c9565b905060200201602081019061074791906135f4565b6001600160a01b03166001600160a01b03168152602001908152602001600020600401600085858481811061077e5761077e6138c9565b905060200201602081019061079391906135f4565b6001600160a01b03166001600160a01b03168152602001908152602001600020548282815181106107c6576107c66138c9565b6020908102919091010152806107db816138f5565b915050610713565b50949350505050565b60006002600054036108105760405162461bcd60e51b81526004016102259061390e565b6002600055603654604051635061f96960e11b81526001600160a01b0380851660048301528492169063a0c3f2d290602401602060405180830381865afa15801561085f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108839190613945565b61089f5760405162461bcd60e51b815260040161022590613967565b6108ab33868686611d63565b600160005595945050505050565b603654604051635061f96960e11b81526001600160a01b0380841660048301528392169063a0c3f2d290602401602060405180830381865afa158015610903573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109279190613945565b6109435760405162461bcd60e51b815260040161022590613967565b6001600160a01b0380831660009081526037602052604090206001810154909133911681146109845760405162461bcd60e51b8152600401610225906139af565b603654603954604051636efa12bd60e01b81526001600160a01b0387811660048301526024820192909252911690636efa12bd90604401600060405180830381600087803b1580156109d557600080fd5b505af11580156109e9573d6000803e3d6000fd5b5050505050505050565b60003411610a135760405162461bcd60e51b8152600401610225906139fc565b603654604051635061f96960e11b81526001600160a01b0380841660048301528392169063a0c3f2d290602401602060405180830381865afa158015610a5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a819190613945565b610a9d5760405162461bcd60e51b815260040161022590613967565b6001600160a01b0382166000908152603760205260409020610ac0903334611d9e565b5050565b33610ad76036546001600160a01b031690565b6001600160a01b031614610afd5760405162461bcd60e51b815260040161022590613428565b610b3e858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250879250869150859050611e70565b5050505050565b6060600080603660009054906101000a90046001600160a01b03166001600160a01b031663060406186040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc19190613a3f565b9050836001600160401b03811115610bdb57610bdb6138b3565b604051908082528060200260200182016040528015610c04578160200160208202803683370190505b50925060005b84811015610c7f57858582818110610c2457610c246138c9565b9050602002016020810190610c3991906135f4565b9250610c50838884610c4b878c6111ce565b6122a9565b848281518110610c6257610c626138c9565b602090810291909101015280610c77816138f5565b915050610c0a565b5050509392505050565b6060816001600160401b03811115610ca357610ca36138b3565b604051908082528060200260200182016040528015610ccc578160200160208202803683370190505b50905060005b82811015610d585760376000858584818110610cf057610cf06138c9565b9050602002016020810190610d0591906135f4565b6001600160a01b03166001600160a01b0316815260200190815260200160002060020154828281518110610d3b57610d3b6138c9565b602090810291909101015280610d50816138f5565b915050610cd2565b5092915050565b600260005403610d815760405162461bcd60e51b81526004016102259061390e565b600260009081556001600160a01b03831681526037602052604090203390610daa9082846123cb565b610db481836125e3565b610dd05760405162461bcd60e51b815260040161022590613a58565b5050600160005550565b60d154610100900460ff1615808015610dfa575060d154600160ff909116105b80610e145750303b158015610e14575060d15460ff166001145b610e775760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610225565b60d1805460ff191660011790558015610e9a5760d1805461ff0019166101001790555b610ea385612649565b610eac8461269e565b610eb5836126d3565b610ebe82612708565b8015610b3e5760d1805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b60003411610f2a5760405162461bcd60e51b8152600401610225906139fc565b603654604051635061f96960e11b81526001600160a01b0380841660048301528392169063a0c3f2d290602401602060405180830381865afa158015610f74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f989190613945565b610fb45760405162461bcd60e51b815260040161022590613967565b336000908152603a60205260409020546001600160a01b0316156110405760405162461bcd60e51b815260206004820152603960248201527f44656c656761746f725374616b696e673a2061646d696e206f6620616e20616360448201527f7469766520706f6f6c2063616e6e6f742064656c6567617465000000000000006064820152608401610225565b6001600160a01b0382166000908152603760205260409020610ac090333461273d565b61106b612804565b6001600160a01b0316336001600160a01b03161461109b5760405162461bcd60e51b815260040161022590613aa0565b6110a48161269e565b50565b60006110c083836110b6612832565b610c4b87876111ce565b90505b92915050565b6002600054036110eb5760405162461bcd60e51b81526004016102259061390e565b6002600055603654604051635061f96960e11b81526001600160a01b0380851660048301528492169063a0c3f2d290602401602060405180830381865afa15801561113a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115e9190613945565b61117a5760405162461bcd60e51b815260040161022590613967565b6001600160a01b0384166000908152603760205260409020339061119f9082856123cb565b6001600160a01b03841660009081526037602052604090206111c290828561273d565b50506001600055505050565b6001600160a01b0391821660009081526037602090815260408083209390941682526004909201909152205490565b611205612804565b6001600160a01b0316336001600160a01b0316146112355760405162461bcd60e51b815260040161022590613aa0565b6110a4816126d3565b6060816001600160401b03811115611258576112586138b3565b604051908082528060200260200182016040528015611281578160200160208202803683370190505b50905060005b82811015610d58576112b98484838181106112a4576112a46138c9565b905060200201602081019061044891906135f4565b8282815181106112cb576112cb6138c9565b6020908102919091010152806112e0816138f5565b915050611287565b603654604051635061f96960e11b81526001600160a01b0380861660048301528592169063a0c3f2d290602401602060405180830381865afa158015611332573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113569190613945565b6113725760405162461bcd60e51b815260040161022590613967565b6001600160a01b0380851660009081526037602052604090206001810154909133911681146113b35760405162461bcd60e51b8152600401610225906139af565b60365460405163e5125a1d60e01b81526001600160a01b03888116600483015260248201889052604482018790529091169063e5125a1d90606401600060405180830381600087803b15801561140857600080fd5b505af115801561141c573d6000803e3d6000fd5b50505050505050505050565b60026000540361144a5760405162461bcd60e51b81526004016102259061390e565b6002600055821580159061145d57508281145b6114b85760405162461bcd60e51b815260206004820152602660248201527f44656c656761746f725374616b696e673a20696e76616c6964206172726179206044820152650d8cadccee8d60d31b6064820152608401610225565b336000805b8581101561156a578484828181106114d7576114d76138c9565b90506020020135826114e99190613ae2565b915061155860376000898985818110611504576115046138c9565b905060200201602081019061151991906135f4565b6001600160a01b03166001600160a01b031681526020019081526020016000208487878581811061154c5761154c6138c9565b905060200201356123cb565b80611562816138f5565b9150506114bd565b5061157582826125e3565b6115915760405162461bcd60e51b815260040161022590613a58565b5050600160005550505050565b6115a6612804565b6001600160a01b0316336001600160a01b0316146115d65760405162461bcd60e51b815260040161022590613aa0565b6110a481612708565b603654604051635061f96960e11b81526001600160a01b038084166004830152600092839283928692169063a0c3f2d290602401602060405180830381865afa158015611630573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116549190613945565b6116705760405162461bcd60e51b815260040161022590613967565b505050506001600160a01b03908116600090815260376020526040902060018101546002820154600390920154921692909190565b6002600054036116c75760405162461bcd60e51b81526004016102259061390e565b6002600055603654604051635061f96960e11b81526001600160a01b0380851660048301528492169063a0c3f2d290602401602060405180830381865afa158015611716573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061173a9190613945565b6117565760405162461bcd60e51b815260040161022590613967565b600082116117a65760405162461bcd60e51b815260206004820181905260248201527f43616e6469646174655374616b696e673a20696e76616c696420616d6f756e746044820152606401610225565b6001600160a01b038316600090815260376020526040812060028101543392906117d1908690613af5565b9050606c5481101561183b5760405162461bcd60e51b815260206004820152602d60248201527f43616e6469646174655374616b696e673a20696e76616c6964207374616b696e60448201526c19c8185b5bdd5b9d081b19599d609a1b6064820152608401610225565b6118468284876128a4565b61185083866125e3565b6115915760405162461bcd60e51b815260206004820152602860248201527f43616e6469646174655374616b696e673a20636f756c64206e6f74207472616e60448201526739b332b9102927a760c11b6064820152608401610225565b6000336118c26036546001600160a01b031690565b6001600160a01b0316146118e85760405162461bcd60e51b815260040161022590613428565b6001600160a01b038316600090815260376020526040902061190a9083612a37565b905060006119206036546001600160a01b031690565b905061192c8183612ad5565b610d5857604080518381524760208201526001600160a01b0380841692908716917f63701cd972aa3c7f87898aab145c972e52185beab07d6e39380a998d334cf6c8910160405180910390a35092915050565b611987612804565b6001600160a01b0316336001600160a01b0316146119b75760405162461bcd60e51b815260040161022590613aa0565b6000816001600160a01b03163b11611a235760405162461bcd60e51b815260206004820152602960248201527f48617356616c696461746f72436f6e74726163743a2073657420746f206e6f6e6044820152680b58dbdb9d1c9858dd60ba1b6064820152608401610225565b6110a481612649565b600260005403611a4e5760405162461bcd60e51b81526004016102259061390e565b60026000908155338152603a60205260409020546001600160a01b031615611ac75760405162461bcd60e51b815260206004820152602660248201527f43616e6469646174655374616b696e673a20706f6f6c2061646d696e2069732060448201526561637469766560d01b6064820152608401610225565b3433611ad881888888888888612b31565b6001600160a01b0380871660008181526037602081815260408084206001810180549789166001600160a01b0319988916811790915581548816871782558552603a835290842080549096168517909555929091529052611b3a818385611d9e565b816001600160a01b0316876001600160a01b03167ffc1f1e73948cbc47c5b7f90e5601b7daccd9ad7173218486ccc74bdd051d05e860405160405180910390a350506001600055505050505050565b33611b9c6036546001600160a01b031690565b6001600160a01b031614611bc25760405162461bcd60e51b815260040161022590613428565b8015610ac0576000805b82811015611cd957600060376000868685818110611bec57611bec6138c9565b9050602002016020810190611c0191906135f4565b6001600160a01b0390811682526020808301939093526040918201600090812060018101549092168152603a909352912080546001600160a01b03191690556002810154935090508215611cc657611c598184612a37565b506001810154611c72906001600160a01b031684612ad5565b611cc65760018101548154604080518681524760208201526001600160a01b0393841693909216917f7dc5115a5aba081f5a174f56a3d02eea582824783322a4ac03f7bd388f444194910160405180910390a35b5080611cd1816138f5565b915050611bcc565b507f4f257d3ba23679d338f1d94296086bba5724af341b7fa31aa0ff297bfcdc62d88383604051611d0b929190613b08565b60405180910390a1505050565b6000600260005403611d3c5760405162461bcd60e51b81526004016102259061390e565b6002600055611d4c338484612ede565b9050611d583382612f40565b600160005592915050565b6000611d70858585612ede565b6001600160a01b0383166000908152603760205260409020909150611d9690868361273d565b949350505050565b6001830154839083906001600160a01b03808316911614611dd15760405162461bcd60e51b8152600401610225906139af565b82856002016000828254611de59190613ae2565b92505081905550611e0b85858760020154868960030154611e069190613ae2565b612fc7565b6001600160a01b03808516600090815260058701602052604090819020429055865490519116907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d90611e619086815260200190565b60405180910390a25050505050565b83518214611eb957807fae52c603227f64e4c6101dde593aa9790a16b3ac77546bd746d758511e9560a5858585604051611eac93929190613b8f565b60405180910390a26122a3565b600080600080600088516001600160401b03811115611eda57611eda6138b3565b604051908082528060200260200182016040528015611f03578160200160208202803683370190505b509050600089516001600160401b03811115611f2157611f216138b3565b604051908082528060200260200182016040528015611f4a578160200160208202803683370190505b50905060008a516001600160401b03811115611f6857611f686138b3565b604051908082528060200260200182016040528015611f91578160200160208202803683370190505b50905060005b8b5181101561220e578b8181518110611fb257611fb26138c9565b6020908102919091018101516001600160a01b038116600090815260038084526040808320603790955290912001549097506001600160a01b03881660009081526001602081815260408084208f855290915290912001549096508a900361205857868389612020816138f5565b9a5081518110612032576120326138c9565b60200260200101906001600160a01b031690816001600160a01b031681525050506121fc565b60028101548a111561208657604080518082019091528681526020018a905260018101869055600281018a90555b6001810154156120d05760018101548c8c848181106120a7576120a76138c9565b90506020020135670de0b6b3a76400006120c19190613bd9565b6120cb9190613bf0565b6120d3565b60005b9850888160000160008282546120e99190613ae2565b91829055509050856120fb8a85613af5565b8151811061210b5761210b6138c9565b6020026020010181815250506040518060400160405280826000015481526020018b81525060016000896001600160a01b03166001600160a01b0316815260200190815260200160002060008c815260200190815260200160002060008201518160000155602082015181600101559050508581600101600001541461219357600181018690555b6001810154846121a38a85613af5565b815181106121b3576121b36138c9565b6020908102919091010152868d6121ca8a85613af5565b815181106121da576121da6138c9565b60200260200101906001600160a01b031690816001600160a01b031681525050505b80612206816138f5565b915050611f97565b50851561225757858152858b51038b52877fee74f10cc50bf4b7e57fd36be7d46288795f3a9151dae97505b718b392ba14a38260405161224e9190613c12565b60405180910390a25b8a511561229b57877f0e54e0485f70f0f63bc25889ddbf01ce1269ad6f07fdb2df573a0fbdb4d66f888c858560405161229293929190613c25565b60405180910390a25b505050505050505b50505050565b6001600160a01b038085166000908152600260209081526040808320938716835292905290812060038101548490036122e457549050611d96565b6001600160a01b03861660009081526003602081815260408084206001808452828620948701548652939092528320918201548392901561236f576001600160a01b038a16600090815260016020818152604080842060038a0154855290915290912054908601549094506123599085613af5565b85600201546123689190613bd9565b9250612377565b846001015493505b8154600090612387908690613af5565b6123919089613bd9565b9050670de0b6b3a76400006123a68286613ae2565b6123b09190613bf0565b86546123bc9190613ae2565b9b9a5050505050505050505050565b6001830154839083906001600160a01b038083169116036123fe5760405162461bcd60e51b815260040161022590613c68565b6000831161244e5760405162461bcd60e51b815260206004820181905260248201527f44656c656761746f725374616b696e673a20696e76616c696420616d6f756e746044820152606401610225565b6001600160a01b03841660009081526004860160205260409020548311156124d45760405162461bcd60e51b815260206004820152603360248201527f44656c656761746f725374616b696e673a20696e73756666696369656e7420616044820152726d6f756e7420746f20756e64656c656761746560681b6064820152608401610225565b6038546001600160a01b038516600090815260058701602052604090205442916124fd91613ae2565b106125595760405162461bcd60e51b815260206004820152602660248201527f44656c656761746f725374616b696e673a20756e64656c656761746520746f6f604482015265206561726c7960d01b6064820152608401610225565b6001600160a01b03841660009081526004860160205260409020546125979086908690612587908790613af5565b868960030154611e069190613af5565b84546040518481526001600160a01b03918216918616907f4d10bd049775c77bd7f255195afba5088028ecb3c7c277d393ccff7934f2f92c906020015b60405180910390a35050505050565b60008147101561263f5760405162461bcd60e51b815260206004820152602160248201527f524f4e5472616e736665723a20696e73756666696369656e742062616c616e636044820152606560f81b6064820152608401610225565b6110c08383612ad5565b603680546001600160a01b0319166001600160a01b0383169081179091556040519081527fef40dc07567635f84f5edbd2f8dbc16b40d9d282dd8e7e6f4ff58236b6836169906020015b60405180910390a150565b606c8190556040518181527f372bbdb8d72373b0012f84ee5a11671e5fb72b8bea902ebca93a19cb45d32be290602001612693565b60388190556040518181527f4956b65267b8f1e642284bcb5037116c69a9c78d9ca576beeae0974737a4872a90602001612693565b60398190556040518181527f02be0b73b597f2c0f138aebee162b3b0e25d5b5a26854c15dcf79176e9a1c67890602001612693565b6001830154839083906001600160a01b038083169116036127705760405162461bcd60e51b815260040161022590613c68565b6001600160a01b03841660009081526004860160205260409020546127ae908690869061279e908790613ae2565b868960030154611e069190613ae2565b6001600160a01b03808516600081815260058801602052604090819020429055875490519216917fe5541a6b6103d4fa7e021ed54fad39c66f27a76bd13d374cf6240ae6bd0bb72b906125d49087815260200190565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103546001600160a01b031690565b6036546040805162c080c360e31b815290516000926001600160a01b03169163060406189160048083019260209291908290030181865afa15801561287b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061289f9190613a3f565b905090565b6001830154839083906001600160a01b038083169116146128d75760405162461bcd60e51b8152600401610225906139af565b84600201548311156129415760405162461bcd60e51b815260206004820152602d60248201527f43616e6469646174655374616b696e673a20696e73756666696369656e74207360448201526c1d185ada5b99c8185b5bdd5b9d609a1b6064820152608401610225565b6038546001600160a01b0385166000908152600587016020526040902054429161296a91613ae2565b11156129c45760405162461bcd60e51b815260206004820152602360248201527f43616e6469646174655374616b696e673a20756e7374616b6520746f6f206561604482015262726c7960e81b6064820152608401610225565b828560020160008282546129d89190613af5565b925050819055506129f985858760020154868960030154611e069190613af5565b84546040518481526001600160a01b03909116907f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f7590602001611e61565b6000612a47836002015483613002565b905080836002016000828254612a5d9190613af5565b9091555050600183015460028401546003850154612a8e9286926001600160a01b0390911691611e06908690613af5565b82546040518281526001600160a01b03909116907f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f759060200160405180910390a292915050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612b22576040519150601f19603f3d011682016040523d82523d6000602084013e612b27565b606091505b5090949350505050565b612b3c8760006125e3565b612ba05760405162461bcd60e51b815260206004820152602f60248201527f43616e6469646174655374616b696e673a20706f6f6c2061646d696e2063616e60448201526e3737ba103932b1b2b4bb32902927a760891b6064820152608401610225565b612bab8460006125e3565b612c0d5760405162461bcd60e51b815260206004820152602d60248201527f43616e6469646174655374616b696e673a2074726561737572792063616e6e6f60448201526c3a103932b1b2b4bb32902927a760991b6064820152608401610225565b606c54811015612c6d5760405162461bcd60e51b815260206004820152602560248201527f43616e6469646174655374616b696e673a20696e73756666696369656e7420616044820152641b5bdd5b9d60da1b6064820152608401610225565b856001600160a01b0316876001600160a01b0316148015612c9f5750836001600160a01b0316866001600160a01b0316145b612d1b5760405162461bcd60e51b815260206004820152604160248201527f43616e6469646174655374616b696e673a20746872656520696e74657261637460448201527f696f6e20616464726573736573206d757374206265206f66207468652073616d6064820152606560f81b608482015260a401610225565b60408051600380825260808201909252600091602082016060803683370190505090508781600081518110612d5257612d526138c9565b60200260200101906001600160a01b031690816001600160a01b0316815250508581600181518110612d8657612d866138c9565b60200260200101906001600160a01b031690816001600160a01b0316815250508381600281518110612dba57612dba6138c9565b60200260200101906001600160a01b031690816001600160a01b031681525050612de381613018565b15612e565760405162461bcd60e51b815260206004820152603c60248201527f43616e6469646174655374616b696e673a207468726565206f7065726174696f60448201527f6e20616464726573736573206d7573742062652064697374696e6374000000006064820152608401610225565b603654604051630733ec9760e41b81526001600160a01b038981166004830152888116602483015287811660448301528681166064830152608482018690529091169063733ec9709060a401600060405180830381600087803b158015612ebc57600080fd5b505af1158015612ed0573d6000803e3d6000fd5b505050505050505050505050565b6000805b82811015612f3857612f1a848483818110612eff57612eff6138c9565b9050602002016020810190612f1491906135f4565b866130df565b612f249083613ae2565b915080612f30816138f5565b915050612ee2565b509392505050565b612f4a82826125e3565b610ac05760405162461bcd60e51b815260206004820152604260248201527f524f4e5472616e736665723a20756e61626c6520746f207472616e736665722060448201527f76616c75652c20726563697069656e74206d6179206861766520726576657274606482015261195960f21b608482015260a401610225565b8354612fdd906001600160a01b031684846131c7565b60038401556001600160a01b0390911660009081526004909201602052604090912055565b600081831061301157816110c0565b5090919050565b6000815160000361302b57506000919050565b60005b6001835161303c9190613af5565b8110156130d6576000613050826001613ae2565b90505b83518110156130c35783818151811061306e5761306e6138c9565b60200260200101516001600160a01b0316848381518110613091576130916138c9565b60200260200101516001600160a01b0316036130b1575060019392505050565b806130bb816138f5565b915050613053565b50806130ce816138f5565b91505061302e565b50600092915050565b6000806130ea612832565b90506130fc848483610c4b88886111ce565b9150826001600160a01b0316846001600160a01b03167f0aa4d283470c904c551d18bb894d37e17674920f3261a7f854be501e25f421b78460405161314391815260200190565b60405180910390a36001600160a01b0384811660008181526002602090815260408083209488168084529482528083208381556003808201889055858552835281842054600182015590519283529392917faa7c29611027fd4be148712bb54960253b7a7d5998c17769bfc424c2f5f185ad910160405180910390a3505092915050565b60006131d1612832565b6001600160a01b038516600090815260036020526040902060018101546002820154929350909183111561324557604051806040016040528061322c886001600160a01b031660009081526037602052604090206003015490565b8152602090810185905281516001850155015160028301555b6001600160a01b03808716600090815260026020908152604080832093891683529290529081209061327788886111ce565b90506000613287898988856122a9565b835490915081146132d9578083556040518181526001600160a01b0389811691908b16907faa7c29611027fd4be148712bb54960253b7a7d5998c17769bfc424c2f5f185ad9060200160405180910390a35b6132e68584888a86613358565b845460018085019190915560038401879055850154841461334d57886001600160a01b0316867f81faf50e2aaf52eaba2ab841071efb9f6f0850a3e7d008b1336e6001d3d4963c876001016000015460405161334491815260200190565b60405180910390a35b505050505050505050565b828460030154101561336c57600284018190555b600061337c856002015484613002565b905060008186600201546133909190613af5565b9050801561341f576002860182905560018701548111156134025760405162461bcd60e51b815260206004820152602660248201527f52657761726443616c63756c6174696f6e3a20696e76616c696420706f6f6c2060448201526573686172657360d01b6064820152608401610225565b808760010160000160008282546134199190613af5565b90915550505b50505050505050565b6020808252603e908201527f48617356616c696461746f72436f6e74726163743a206d6574686f642063616c60408201527f6c6572206d7573742062652076616c696461746f7220636f6e74726163740000606082015260800190565b60008083601f84011261349757600080fd5b5081356001600160401b038111156134ae57600080fd5b6020830191508360208260051b85010111156134c957600080fd5b9250929050565b600080600080604085870312156134e657600080fd5b84356001600160401b03808211156134fd57600080fd5b61350988838901613485565b9096509450602087013591508082111561352257600080fd5b5061352f87828801613485565b95989497509550505050565b600081518084526020808501945080840160005b8381101561356b5781518752958201959082019060010161354f565b509495945050505050565b6020815260006110c0602083018461353b565b6001600160a01b03811681146110a457600080fd5b6000806000604084860312156135b357600080fd5b83356001600160401b038111156135c957600080fd5b6135d586828701613485565b90945092505060208401356135e981613589565b809150509250925092565b60006020828403121561360657600080fd5b813561361181613589565b9392505050565b60008060008060006060868803121561363057600080fd5b85356001600160401b038082111561364757600080fd5b61365389838a01613485565b9097509550602088013591508082111561366c57600080fd5b5061367988828901613485565b96999598509660400135949350505050565b6000806000604084860312156136a057600080fd5b83356136ab81613589565b925060208401356001600160401b038111156136c657600080fd5b6136d286828701613485565b9497909650939450505050565b600080602083850312156136f257600080fd5b82356001600160401b0381111561370857600080fd5b61371485828601613485565b90969095509350505050565b6000806040838503121561373357600080fd5b823561373e81613589565b946020939093013593505050565b6000806000806080858703121561376257600080fd5b843561376d81613589565b966020860135965060408601359560600135945092505050565b60006020828403121561379957600080fd5b5035919050565b600080604083850312156137b357600080fd5b82356137be81613589565b915060208301356137ce81613589565b809150509250929050565b6000806000606084860312156137ee57600080fd5b83356137f981613589565b9250602084013561380981613589565b929592945050506040919091013590565b60008060006060848603121561382f57600080fd5b833561383a81613589565b95602085013595506040909401359392505050565b600080600080600060a0868803121561386757600080fd5b853561387281613589565b9450602086013561388281613589565b9350604086013561389281613589565b925060608601356138a281613589565b949793965091946080013592915050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201613907576139076138df565b5060010190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60006020828403121561395757600080fd5b8151801515811461361157600080fd5b60208082526028908201527f426173655374616b696e673a20717565727920666f72206e6f6e2d6578697374604082015267195b9d081c1bdbdb60c21b606082015260800190565b6020808252602d908201527f426173655374616b696e673a20726571756573746572206d757374206265207460408201526c3432903837b7b61030b236b4b760991b606082015260800190565b60208082526023908201527f426173655374616b696e673a207175657279207769746820656d7074792076616040820152626c756560e81b606082015260800190565b600060208284031215613a5157600080fd5b5051919050565b60208082526028908201527f44656c656761746f725374616b696e673a20636f756c64206e6f74207472616e60408201526739b332b9102927a760c11b606082015260800190565b60208082526022908201527f48617350726f787941646d696e3a20756e617574686f72697a65642073656e6460408201526132b960f11b606082015260800190565b808201808211156110c3576110c36138df565b818103818111156110c3576110c36138df565b60208082528181018390526000908460408401835b86811015613b4b578235613b3081613589565b6001600160a01b031682529183019190830190600101613b1d565b509695505050505050565b600081518084526020808501945080840160005b8381101561356b5781516001600160a01b031687529582019590820190600101613b6a565b604081526000613ba26040830186613b56565b82810360208401528381526001600160fb1b03841115613bc157600080fd5b8360051b808660208401370160200195945050505050565b80820281158282048414176110c3576110c36138df565b600082613c0d57634e487b7160e01b600052601260045260246000fd5b500490565b6020815260006110c06020830184613b56565b606081526000613c386060830186613b56565b8281036020840152613c4a818661353b565b90508281036040840152613c5e818561353b565b9695505050505050565b60208082526031908201527f426173655374616b696e673a2064656c656761746f72206d757374206e6f74206040820152703132903a3432903837b7b61030b236b4b760791b60608201526080019056fea264697066735822122018731fe3e302ebe1194cd21918a9de58aa42af0abc5bb778de747a024890b31064736f6c63430008110033", - "deployedBytecode": "0x6080604052600436106101e75760003560e01c8063895ab74211610102578063af24542911610095578063e115877b11610064578063e115877b146105dd578063e5376f5414610628578063e9ac5e061461063b578063f9f031df1461065b57610230565b8063af24542914610568578063c2a672e01461057d578063c905bb351461059d578063cdf64a76146105bd57610230565b80639488e4e9116100d15780639488e4e9146104bb578063969ffc14146104db57806399439089146104fb5780639e614e0e1461052357610230565b8063895ab7421461042d578063909791dd1461046657806391f8723f1461047b578063924f081e1461049b57610230565b80634d99dd161161017a5780636b091695116101495780636b091695146103ad5780636bd8f804146103cd57806376664b65146103ed578063888b9ae91461040d57610230565b80634d99dd161461033a5780634ec81af11461035a5780635c19a95c1461037a578063679a6e431461038d57610230565b806326476204116101b657806326476204146102d45780633b8cb16b146102e75780633d8e846e146102fa57806342ef3c341461031a57610230565b80630682e8fa14610243578063095f647514610267578063097e4a9d146102945780631658c86e146102b457610230565b3661023057336101ff6036546001600160a01b031690565b6001600160a01b03161461022e5760405162461bcd60e51b815260040161022590613428565b60405180910390fd5b005b336101ff6036546001600160a01b031690565b34801561024f57600080fd5b506038545b6040519081526020015b60405180910390f35b34801561027357600080fd5b506102876102823660046134d0565b61067b565b60405161025e9190613576565b3480156102a057600080fd5b506102546102af36600461359e565b6107ec565b3480156102c057600080fd5b5061022e6102cf3660046135f4565b6108b9565b61022e6102e23660046135f4565b6109f3565b61022e6102f5366004613618565b610ac4565b34801561030657600080fd5b5061028761031536600461368b565b610b45565b34801561032657600080fd5b506102876103353660046136df565b610c89565b34801561034657600080fd5b5061022e610355366004613720565b610d5f565b34801561036657600080fd5b5061022e61037536600461374c565b610dda565b61022e6103883660046135f4565b610f0a565b34801561039957600080fd5b5061022e6103a8366004613787565b611063565b3480156103b957600080fd5b506102546103c83660046137a0565b6110a7565b3480156103d957600080fd5b5061022e6103e83660046137d9565b6110c9565b3480156103f957600080fd5b506102546104083660046137a0565b6111ce565b34801561041957600080fd5b5061022e610428366004613787565b6111fd565b34801561043957600080fd5b506102546104483660046135f4565b6001600160a01b031660009081526037602052604090206003015490565b34801561047257600080fd5b50606c54610254565b34801561048757600080fd5b506102876104963660046136df565b61123e565b3480156104a757600080fd5b5061022e6104b636600461381a565b6112e8565b3480156104c757600080fd5b5061022e6104d63660046134d0565b611428565b3480156104e757600080fd5b5061022e6104f6366004613787565b61159e565b34801561050757600080fd5b506036546040516001600160a01b03909116815260200161025e565b34801561052f57600080fd5b5061054361053e3660046135f4565b6115df565b604080516001600160a01b03909416845260208401929092529082015260600161025e565b34801561057457600080fd5b50603954610254565b34801561058957600080fd5b5061022e610598366004613720565b6116a5565b3480156105a957600080fd5b506102546105b8366004613720565b6118ad565b3480156105c957600080fd5b5061022e6105d83660046135f4565b61197f565b3480156105e957600080fd5b506106186105f83660046135f4565b6001600160a01b039081166000908152603a602052604090205416151590565b604051901515815260200161025e565b61022e61063636600461384f565b611a2c565b34801561064757600080fd5b5061022e6106563660046136df565b611b89565b34801561066757600080fd5b506102546106763660046136df565b611d18565b60608382146106cc5760405162461bcd60e51b815260206004820181905260248201527f426173655374616b696e673a20696e76616c696420696e7075742061727261796044820152606401610225565b836001600160401b038111156106e4576106e46138b3565b60405190808252806020026020018201604052801561070d578160200160208202803683370190505b50905060005b81518110156107e35760376000878784818110610732576107326138c9565b905060200201602081019061074791906135f4565b6001600160a01b03166001600160a01b03168152602001908152602001600020600401600085858481811061077e5761077e6138c9565b905060200201602081019061079391906135f4565b6001600160a01b03166001600160a01b03168152602001908152602001600020548282815181106107c6576107c66138c9565b6020908102919091010152806107db816138f5565b915050610713565b50949350505050565b60006002600054036108105760405162461bcd60e51b81526004016102259061390e565b6002600055603654604051635061f96960e11b81526001600160a01b0380851660048301528492169063a0c3f2d290602401602060405180830381865afa15801561085f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108839190613945565b61089f5760405162461bcd60e51b815260040161022590613967565b6108ab33868686611d63565b600160005595945050505050565b603654604051635061f96960e11b81526001600160a01b0380841660048301528392169063a0c3f2d290602401602060405180830381865afa158015610903573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109279190613945565b6109435760405162461bcd60e51b815260040161022590613967565b6001600160a01b0380831660009081526037602052604090206001810154909133911681146109845760405162461bcd60e51b8152600401610225906139af565b603654603954604051636efa12bd60e01b81526001600160a01b0387811660048301526024820192909252911690636efa12bd90604401600060405180830381600087803b1580156109d557600080fd5b505af11580156109e9573d6000803e3d6000fd5b5050505050505050565b60003411610a135760405162461bcd60e51b8152600401610225906139fc565b603654604051635061f96960e11b81526001600160a01b0380841660048301528392169063a0c3f2d290602401602060405180830381865afa158015610a5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a819190613945565b610a9d5760405162461bcd60e51b815260040161022590613967565b6001600160a01b0382166000908152603760205260409020610ac0903334611d9e565b5050565b33610ad76036546001600160a01b031690565b6001600160a01b031614610afd5760405162461bcd60e51b815260040161022590613428565b610b3e858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250879250869150859050611e70565b5050505050565b6060600080603660009054906101000a90046001600160a01b03166001600160a01b031663060406186040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc19190613a3f565b9050836001600160401b03811115610bdb57610bdb6138b3565b604051908082528060200260200182016040528015610c04578160200160208202803683370190505b50925060005b84811015610c7f57858582818110610c2457610c246138c9565b9050602002016020810190610c3991906135f4565b9250610c50838884610c4b878c6111ce565b6122a9565b848281518110610c6257610c626138c9565b602090810291909101015280610c77816138f5565b915050610c0a565b5050509392505050565b6060816001600160401b03811115610ca357610ca36138b3565b604051908082528060200260200182016040528015610ccc578160200160208202803683370190505b50905060005b82811015610d585760376000858584818110610cf057610cf06138c9565b9050602002016020810190610d0591906135f4565b6001600160a01b03166001600160a01b0316815260200190815260200160002060020154828281518110610d3b57610d3b6138c9565b602090810291909101015280610d50816138f5565b915050610cd2565b5092915050565b600260005403610d815760405162461bcd60e51b81526004016102259061390e565b600260009081556001600160a01b03831681526037602052604090203390610daa9082846123cb565b610db481836125e3565b610dd05760405162461bcd60e51b815260040161022590613a58565b5050600160005550565b60d154610100900460ff1615808015610dfa575060d154600160ff909116105b80610e145750303b158015610e14575060d15460ff166001145b610e775760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610225565b60d1805460ff191660011790558015610e9a5760d1805461ff0019166101001790555b610ea385612649565b610eac8461269e565b610eb5836126d3565b610ebe82612708565b8015610b3e5760d1805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b60003411610f2a5760405162461bcd60e51b8152600401610225906139fc565b603654604051635061f96960e11b81526001600160a01b0380841660048301528392169063a0c3f2d290602401602060405180830381865afa158015610f74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f989190613945565b610fb45760405162461bcd60e51b815260040161022590613967565b336000908152603a60205260409020546001600160a01b0316156110405760405162461bcd60e51b815260206004820152603960248201527f44656c656761746f725374616b696e673a2061646d696e206f6620616e20616360448201527f7469766520706f6f6c2063616e6e6f742064656c6567617465000000000000006064820152608401610225565b6001600160a01b0382166000908152603760205260409020610ac090333461273d565b61106b612804565b6001600160a01b0316336001600160a01b03161461109b5760405162461bcd60e51b815260040161022590613aa0565b6110a48161269e565b50565b60006110c083836110b6612832565b610c4b87876111ce565b90505b92915050565b6002600054036110eb5760405162461bcd60e51b81526004016102259061390e565b6002600055603654604051635061f96960e11b81526001600160a01b0380851660048301528492169063a0c3f2d290602401602060405180830381865afa15801561113a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115e9190613945565b61117a5760405162461bcd60e51b815260040161022590613967565b6001600160a01b0384166000908152603760205260409020339061119f9082856123cb565b6001600160a01b03841660009081526037602052604090206111c290828561273d565b50506001600055505050565b6001600160a01b0391821660009081526037602090815260408083209390941682526004909201909152205490565b611205612804565b6001600160a01b0316336001600160a01b0316146112355760405162461bcd60e51b815260040161022590613aa0565b6110a4816126d3565b6060816001600160401b03811115611258576112586138b3565b604051908082528060200260200182016040528015611281578160200160208202803683370190505b50905060005b82811015610d58576112b98484838181106112a4576112a46138c9565b905060200201602081019061044891906135f4565b8282815181106112cb576112cb6138c9565b6020908102919091010152806112e0816138f5565b915050611287565b603654604051635061f96960e11b81526001600160a01b0380861660048301528592169063a0c3f2d290602401602060405180830381865afa158015611332573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113569190613945565b6113725760405162461bcd60e51b815260040161022590613967565b6001600160a01b0380851660009081526037602052604090206001810154909133911681146113b35760405162461bcd60e51b8152600401610225906139af565b60365460405163e5125a1d60e01b81526001600160a01b03888116600483015260248201889052604482018790529091169063e5125a1d90606401600060405180830381600087803b15801561140857600080fd5b505af115801561141c573d6000803e3d6000fd5b50505050505050505050565b60026000540361144a5760405162461bcd60e51b81526004016102259061390e565b6002600055821580159061145d57508281145b6114b85760405162461bcd60e51b815260206004820152602660248201527f44656c656761746f725374616b696e673a20696e76616c6964206172726179206044820152650d8cadccee8d60d31b6064820152608401610225565b336000805b8581101561156a578484828181106114d7576114d76138c9565b90506020020135826114e99190613ae2565b915061155860376000898985818110611504576115046138c9565b905060200201602081019061151991906135f4565b6001600160a01b03166001600160a01b031681526020019081526020016000208487878581811061154c5761154c6138c9565b905060200201356123cb565b80611562816138f5565b9150506114bd565b5061157582826125e3565b6115915760405162461bcd60e51b815260040161022590613a58565b5050600160005550505050565b6115a6612804565b6001600160a01b0316336001600160a01b0316146115d65760405162461bcd60e51b815260040161022590613aa0565b6110a481612708565b603654604051635061f96960e11b81526001600160a01b038084166004830152600092839283928692169063a0c3f2d290602401602060405180830381865afa158015611630573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116549190613945565b6116705760405162461bcd60e51b815260040161022590613967565b505050506001600160a01b03908116600090815260376020526040902060018101546002820154600390920154921692909190565b6002600054036116c75760405162461bcd60e51b81526004016102259061390e565b6002600055603654604051635061f96960e11b81526001600160a01b0380851660048301528492169063a0c3f2d290602401602060405180830381865afa158015611716573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061173a9190613945565b6117565760405162461bcd60e51b815260040161022590613967565b600082116117a65760405162461bcd60e51b815260206004820181905260248201527f43616e6469646174655374616b696e673a20696e76616c696420616d6f756e746044820152606401610225565b6001600160a01b038316600090815260376020526040812060028101543392906117d1908690613af5565b9050606c5481101561183b5760405162461bcd60e51b815260206004820152602d60248201527f43616e6469646174655374616b696e673a20696e76616c6964207374616b696e60448201526c19c8185b5bdd5b9d081b19599d609a1b6064820152608401610225565b6118468284876128a4565b61185083866125e3565b6115915760405162461bcd60e51b815260206004820152602860248201527f43616e6469646174655374616b696e673a20636f756c64206e6f74207472616e60448201526739b332b9102927a760c11b6064820152608401610225565b6000336118c26036546001600160a01b031690565b6001600160a01b0316146118e85760405162461bcd60e51b815260040161022590613428565b6001600160a01b038316600090815260376020526040902061190a9083612a37565b905060006119206036546001600160a01b031690565b905061192c8183612ad5565b610d5857604080518381524760208201526001600160a01b0380841692908716917f63701cd972aa3c7f87898aab145c972e52185beab07d6e39380a998d334cf6c8910160405180910390a35092915050565b611987612804565b6001600160a01b0316336001600160a01b0316146119b75760405162461bcd60e51b815260040161022590613aa0565b6000816001600160a01b03163b11611a235760405162461bcd60e51b815260206004820152602960248201527f48617356616c696461746f72436f6e74726163743a2073657420746f206e6f6e6044820152680b58dbdb9d1c9858dd60ba1b6064820152608401610225565b6110a481612649565b600260005403611a4e5760405162461bcd60e51b81526004016102259061390e565b60026000908155338152603a60205260409020546001600160a01b031615611ac75760405162461bcd60e51b815260206004820152602660248201527f43616e6469646174655374616b696e673a20706f6f6c2061646d696e2069732060448201526561637469766560d01b6064820152608401610225565b3433611ad881888888888888612b31565b6001600160a01b0380871660008181526037602081815260408084206001810180549789166001600160a01b0319988916811790915581548816871782558552603a835290842080549096168517909555929091529052611b3a818385611d9e565b816001600160a01b0316876001600160a01b03167ffc1f1e73948cbc47c5b7f90e5601b7daccd9ad7173218486ccc74bdd051d05e860405160405180910390a350506001600055505050505050565b33611b9c6036546001600160a01b031690565b6001600160a01b031614611bc25760405162461bcd60e51b815260040161022590613428565b8015610ac0576000805b82811015611cd957600060376000868685818110611bec57611bec6138c9565b9050602002016020810190611c0191906135f4565b6001600160a01b0390811682526020808301939093526040918201600090812060018101549092168152603a909352912080546001600160a01b03191690556002810154935090508215611cc657611c598184612a37565b506001810154611c72906001600160a01b031684612ad5565b611cc65760018101548154604080518681524760208201526001600160a01b0393841693909216917f7dc5115a5aba081f5a174f56a3d02eea582824783322a4ac03f7bd388f444194910160405180910390a35b5080611cd1816138f5565b915050611bcc565b507f4f257d3ba23679d338f1d94296086bba5724af341b7fa31aa0ff297bfcdc62d88383604051611d0b929190613b08565b60405180910390a1505050565b6000600260005403611d3c5760405162461bcd60e51b81526004016102259061390e565b6002600055611d4c338484612ede565b9050611d583382612f40565b600160005592915050565b6000611d70858585612ede565b6001600160a01b0383166000908152603760205260409020909150611d9690868361273d565b949350505050565b6001830154839083906001600160a01b03808316911614611dd15760405162461bcd60e51b8152600401610225906139af565b82856002016000828254611de59190613ae2565b92505081905550611e0b85858760020154868960030154611e069190613ae2565b612fc7565b6001600160a01b03808516600090815260058701602052604090819020429055865490519116907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d90611e619086815260200190565b60405180910390a25050505050565b83518214611eb957807fae52c603227f64e4c6101dde593aa9790a16b3ac77546bd746d758511e9560a5858585604051611eac93929190613b8f565b60405180910390a26122a3565b600080600080600088516001600160401b03811115611eda57611eda6138b3565b604051908082528060200260200182016040528015611f03578160200160208202803683370190505b509050600089516001600160401b03811115611f2157611f216138b3565b604051908082528060200260200182016040528015611f4a578160200160208202803683370190505b50905060008a516001600160401b03811115611f6857611f686138b3565b604051908082528060200260200182016040528015611f91578160200160208202803683370190505b50905060005b8b5181101561220e578b8181518110611fb257611fb26138c9565b6020908102919091018101516001600160a01b038116600090815260038084526040808320603790955290912001549097506001600160a01b03881660009081526001602081815260408084208f855290915290912001549096508a900361205857868389612020816138f5565b9a5081518110612032576120326138c9565b60200260200101906001600160a01b031690816001600160a01b031681525050506121fc565b60028101548a111561208657604080518082019091528681526020018a905260018101869055600281018a90555b6001810154156120d05760018101548c8c848181106120a7576120a76138c9565b90506020020135670de0b6b3a76400006120c19190613bd9565b6120cb9190613bf0565b6120d3565b60005b9850888160000160008282546120e99190613ae2565b91829055509050856120fb8a85613af5565b8151811061210b5761210b6138c9565b6020026020010181815250506040518060400160405280826000015481526020018b81525060016000896001600160a01b03166001600160a01b0316815260200190815260200160002060008c815260200190815260200160002060008201518160000155602082015181600101559050508581600101600001541461219357600181018690555b6001810154846121a38a85613af5565b815181106121b3576121b36138c9565b6020908102919091010152868d6121ca8a85613af5565b815181106121da576121da6138c9565b60200260200101906001600160a01b031690816001600160a01b031681525050505b80612206816138f5565b915050611f97565b50851561225757858152858b51038b52877fee74f10cc50bf4b7e57fd36be7d46288795f3a9151dae97505b718b392ba14a38260405161224e9190613c12565b60405180910390a25b8a511561229b57877f0e54e0485f70f0f63bc25889ddbf01ce1269ad6f07fdb2df573a0fbdb4d66f888c858560405161229293929190613c25565b60405180910390a25b505050505050505b50505050565b6001600160a01b038085166000908152600260209081526040808320938716835292905290812060038101548490036122e457549050611d96565b6001600160a01b03861660009081526003602081815260408084206001808452828620948701548652939092528320918201548392901561236f576001600160a01b038a16600090815260016020818152604080842060038a0154855290915290912054908601549094506123599085613af5565b85600201546123689190613bd9565b9250612377565b846001015493505b8154600090612387908690613af5565b6123919089613bd9565b9050670de0b6b3a76400006123a68286613ae2565b6123b09190613bf0565b86546123bc9190613ae2565b9b9a5050505050505050505050565b6001830154839083906001600160a01b038083169116036123fe5760405162461bcd60e51b815260040161022590613c68565b6000831161244e5760405162461bcd60e51b815260206004820181905260248201527f44656c656761746f725374616b696e673a20696e76616c696420616d6f756e746044820152606401610225565b6001600160a01b03841660009081526004860160205260409020548311156124d45760405162461bcd60e51b815260206004820152603360248201527f44656c656761746f725374616b696e673a20696e73756666696369656e7420616044820152726d6f756e7420746f20756e64656c656761746560681b6064820152608401610225565b6038546001600160a01b038516600090815260058701602052604090205442916124fd91613ae2565b106125595760405162461bcd60e51b815260206004820152602660248201527f44656c656761746f725374616b696e673a20756e64656c656761746520746f6f604482015265206561726c7960d01b6064820152608401610225565b6001600160a01b03841660009081526004860160205260409020546125979086908690612587908790613af5565b868960030154611e069190613af5565b84546040518481526001600160a01b03918216918616907f4d10bd049775c77bd7f255195afba5088028ecb3c7c277d393ccff7934f2f92c906020015b60405180910390a35050505050565b60008147101561263f5760405162461bcd60e51b815260206004820152602160248201527f524f4e5472616e736665723a20696e73756666696369656e742062616c616e636044820152606560f81b6064820152608401610225565b6110c08383612ad5565b603680546001600160a01b0319166001600160a01b0383169081179091556040519081527fef40dc07567635f84f5edbd2f8dbc16b40d9d282dd8e7e6f4ff58236b6836169906020015b60405180910390a150565b606c8190556040518181527f372bbdb8d72373b0012f84ee5a11671e5fb72b8bea902ebca93a19cb45d32be290602001612693565b60388190556040518181527f4956b65267b8f1e642284bcb5037116c69a9c78d9ca576beeae0974737a4872a90602001612693565b60398190556040518181527f02be0b73b597f2c0f138aebee162b3b0e25d5b5a26854c15dcf79176e9a1c67890602001612693565b6001830154839083906001600160a01b038083169116036127705760405162461bcd60e51b815260040161022590613c68565b6001600160a01b03841660009081526004860160205260409020546127ae908690869061279e908790613ae2565b868960030154611e069190613ae2565b6001600160a01b03808516600081815260058801602052604090819020429055875490519216917fe5541a6b6103d4fa7e021ed54fad39c66f27a76bd13d374cf6240ae6bd0bb72b906125d49087815260200190565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103546001600160a01b031690565b6036546040805162c080c360e31b815290516000926001600160a01b03169163060406189160048083019260209291908290030181865afa15801561287b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061289f9190613a3f565b905090565b6001830154839083906001600160a01b038083169116146128d75760405162461bcd60e51b8152600401610225906139af565b84600201548311156129415760405162461bcd60e51b815260206004820152602d60248201527f43616e6469646174655374616b696e673a20696e73756666696369656e74207360448201526c1d185ada5b99c8185b5bdd5b9d609a1b6064820152608401610225565b6038546001600160a01b0385166000908152600587016020526040902054429161296a91613ae2565b11156129c45760405162461bcd60e51b815260206004820152602360248201527f43616e6469646174655374616b696e673a20756e7374616b6520746f6f206561604482015262726c7960e81b6064820152608401610225565b828560020160008282546129d89190613af5565b925050819055506129f985858760020154868960030154611e069190613af5565b84546040518481526001600160a01b03909116907f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f7590602001611e61565b6000612a47836002015483613002565b905080836002016000828254612a5d9190613af5565b9091555050600183015460028401546003850154612a8e9286926001600160a01b0390911691611e06908690613af5565b82546040518281526001600160a01b03909116907f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f759060200160405180910390a292915050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612b22576040519150601f19603f3d011682016040523d82523d6000602084013e612b27565b606091505b5090949350505050565b612b3c8760006125e3565b612ba05760405162461bcd60e51b815260206004820152602f60248201527f43616e6469646174655374616b696e673a20706f6f6c2061646d696e2063616e60448201526e3737ba103932b1b2b4bb32902927a760891b6064820152608401610225565b612bab8460006125e3565b612c0d5760405162461bcd60e51b815260206004820152602d60248201527f43616e6469646174655374616b696e673a2074726561737572792063616e6e6f60448201526c3a103932b1b2b4bb32902927a760991b6064820152608401610225565b606c54811015612c6d5760405162461bcd60e51b815260206004820152602560248201527f43616e6469646174655374616b696e673a20696e73756666696369656e7420616044820152641b5bdd5b9d60da1b6064820152608401610225565b856001600160a01b0316876001600160a01b0316148015612c9f5750836001600160a01b0316866001600160a01b0316145b612d1b5760405162461bcd60e51b815260206004820152604160248201527f43616e6469646174655374616b696e673a20746872656520696e74657261637460448201527f696f6e20616464726573736573206d757374206265206f66207468652073616d6064820152606560f81b608482015260a401610225565b60408051600380825260808201909252600091602082016060803683370190505090508781600081518110612d5257612d526138c9565b60200260200101906001600160a01b031690816001600160a01b0316815250508581600181518110612d8657612d866138c9565b60200260200101906001600160a01b031690816001600160a01b0316815250508381600281518110612dba57612dba6138c9565b60200260200101906001600160a01b031690816001600160a01b031681525050612de381613018565b15612e565760405162461bcd60e51b815260206004820152603c60248201527f43616e6469646174655374616b696e673a207468726565206f7065726174696f60448201527f6e20616464726573736573206d7573742062652064697374696e6374000000006064820152608401610225565b603654604051630733ec9760e41b81526001600160a01b038981166004830152888116602483015287811660448301528681166064830152608482018690529091169063733ec9709060a401600060405180830381600087803b158015612ebc57600080fd5b505af1158015612ed0573d6000803e3d6000fd5b505050505050505050505050565b6000805b82811015612f3857612f1a848483818110612eff57612eff6138c9565b9050602002016020810190612f1491906135f4565b866130df565b612f249083613ae2565b915080612f30816138f5565b915050612ee2565b509392505050565b612f4a82826125e3565b610ac05760405162461bcd60e51b815260206004820152604260248201527f524f4e5472616e736665723a20756e61626c6520746f207472616e736665722060448201527f76616c75652c20726563697069656e74206d6179206861766520726576657274606482015261195960f21b608482015260a401610225565b8354612fdd906001600160a01b031684846131c7565b60038401556001600160a01b0390911660009081526004909201602052604090912055565b600081831061301157816110c0565b5090919050565b6000815160000361302b57506000919050565b60005b6001835161303c9190613af5565b8110156130d6576000613050826001613ae2565b90505b83518110156130c35783818151811061306e5761306e6138c9565b60200260200101516001600160a01b0316848381518110613091576130916138c9565b60200260200101516001600160a01b0316036130b1575060019392505050565b806130bb816138f5565b915050613053565b50806130ce816138f5565b91505061302e565b50600092915050565b6000806130ea612832565b90506130fc848483610c4b88886111ce565b9150826001600160a01b0316846001600160a01b03167f0aa4d283470c904c551d18bb894d37e17674920f3261a7f854be501e25f421b78460405161314391815260200190565b60405180910390a36001600160a01b0384811660008181526002602090815260408083209488168084529482528083208381556003808201889055858552835281842054600182015590519283529392917faa7c29611027fd4be148712bb54960253b7a7d5998c17769bfc424c2f5f185ad910160405180910390a3505092915050565b60006131d1612832565b6001600160a01b038516600090815260036020526040902060018101546002820154929350909183111561324557604051806040016040528061322c886001600160a01b031660009081526037602052604090206003015490565b8152602090810185905281516001850155015160028301555b6001600160a01b03808716600090815260026020908152604080832093891683529290529081209061327788886111ce565b90506000613287898988856122a9565b835490915081146132d9578083556040518181526001600160a01b0389811691908b16907faa7c29611027fd4be148712bb54960253b7a7d5998c17769bfc424c2f5f185ad9060200160405180910390a35b6132e68584888a86613358565b845460018085019190915560038401879055850154841461334d57886001600160a01b0316867f81faf50e2aaf52eaba2ab841071efb9f6f0850a3e7d008b1336e6001d3d4963c876001016000015460405161334491815260200190565b60405180910390a35b505050505050505050565b828460030154101561336c57600284018190555b600061337c856002015484613002565b905060008186600201546133909190613af5565b9050801561341f576002860182905560018701548111156134025760405162461bcd60e51b815260206004820152602660248201527f52657761726443616c63756c6174696f6e3a20696e76616c696420706f6f6c2060448201526573686172657360d01b6064820152608401610225565b808760010160000160008282546134199190613af5565b90915550505b50505050505050565b6020808252603e908201527f48617356616c696461746f72436f6e74726163743a206d6574686f642063616c60408201527f6c6572206d7573742062652076616c696461746f7220636f6e74726163740000606082015260800190565b60008083601f84011261349757600080fd5b5081356001600160401b038111156134ae57600080fd5b6020830191508360208260051b85010111156134c957600080fd5b9250929050565b600080600080604085870312156134e657600080fd5b84356001600160401b03808211156134fd57600080fd5b61350988838901613485565b9096509450602087013591508082111561352257600080fd5b5061352f87828801613485565b95989497509550505050565b600081518084526020808501945080840160005b8381101561356b5781518752958201959082019060010161354f565b509495945050505050565b6020815260006110c0602083018461353b565b6001600160a01b03811681146110a457600080fd5b6000806000604084860312156135b357600080fd5b83356001600160401b038111156135c957600080fd5b6135d586828701613485565b90945092505060208401356135e981613589565b809150509250925092565b60006020828403121561360657600080fd5b813561361181613589565b9392505050565b60008060008060006060868803121561363057600080fd5b85356001600160401b038082111561364757600080fd5b61365389838a01613485565b9097509550602088013591508082111561366c57600080fd5b5061367988828901613485565b96999598509660400135949350505050565b6000806000604084860312156136a057600080fd5b83356136ab81613589565b925060208401356001600160401b038111156136c657600080fd5b6136d286828701613485565b9497909650939450505050565b600080602083850312156136f257600080fd5b82356001600160401b0381111561370857600080fd5b61371485828601613485565b90969095509350505050565b6000806040838503121561373357600080fd5b823561373e81613589565b946020939093013593505050565b6000806000806080858703121561376257600080fd5b843561376d81613589565b966020860135965060408601359560600135945092505050565b60006020828403121561379957600080fd5b5035919050565b600080604083850312156137b357600080fd5b82356137be81613589565b915060208301356137ce81613589565b809150509250929050565b6000806000606084860312156137ee57600080fd5b83356137f981613589565b9250602084013561380981613589565b929592945050506040919091013590565b60008060006060848603121561382f57600080fd5b833561383a81613589565b95602085013595506040909401359392505050565b600080600080600060a0868803121561386757600080fd5b853561387281613589565b9450602086013561388281613589565b9350604086013561389281613589565b925060608601356138a281613589565b949793965091946080013592915050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201613907576139076138df565b5060010190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60006020828403121561395757600080fd5b8151801515811461361157600080fd5b60208082526028908201527f426173655374616b696e673a20717565727920666f72206e6f6e2d6578697374604082015267195b9d081c1bdbdb60c21b606082015260800190565b6020808252602d908201527f426173655374616b696e673a20726571756573746572206d757374206265207460408201526c3432903837b7b61030b236b4b760991b606082015260800190565b60208082526023908201527f426173655374616b696e673a207175657279207769746820656d7074792076616040820152626c756560e81b606082015260800190565b600060208284031215613a5157600080fd5b5051919050565b60208082526028908201527f44656c656761746f725374616b696e673a20636f756c64206e6f74207472616e60408201526739b332b9102927a760c11b606082015260800190565b60208082526022908201527f48617350726f787941646d696e3a20756e617574686f72697a65642073656e6460408201526132b960f11b606082015260800190565b808201808211156110c3576110c36138df565b818103818111156110c3576110c36138df565b60208082528181018390526000908460408401835b86811015613b4b578235613b3081613589565b6001600160a01b031682529183019190830190600101613b1d565b509695505050505050565b600081518084526020808501945080840160005b8381101561356b5781516001600160a01b031687529582019590820190600101613b6a565b604081526000613ba26040830186613b56565b82810360208401528381526001600160fb1b03841115613bc157600080fd5b8360051b808660208401370160200195945050505050565b80820281158282048414176110c3576110c36138df565b600082613c0d57634e487b7160e01b600052601260045260246000fd5b500490565b6020815260006110c06020830184613b56565b606081526000613c386060830186613b56565b8281036020840152613c4a818661353b565b90508281036040840152613c5e818561353b565b9695505050505050565b60208082526031908201527f426173655374616b696e673a2064656c656761746f72206d757374206e6f74206040820152703132903a3432903837b7b61030b236b4b760791b60608201526080019056fea264697066735822122018731fe3e302ebe1194cd21918a9de58aa42af0abc5bb778de747a024890b31064736f6c63430008110033", + "numDeployments": 4, + "solcInputHash": "9c14b324033beb5ee990c4b68d9e780e", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"minSecs\",\"type\":\"uint256\"}],\"name\":\"CooldownSecsToUndelegateUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"consensuAddr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Delegated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"name\":\"MinValidatorStakingAmountUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"validator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"PoolApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"poolAddr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"shares\",\"type\":\"uint256\"}],\"name\":\"PoolSharesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"validator\",\"type\":\"address[]\"}],\"name\":\"PoolsDeprecated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"poolAddrs\",\"type\":\"address[]\"}],\"name\":\"PoolsUpdateConflicted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"poolAddrs\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"rewards\",\"type\":\"uint256[]\"}],\"name\":\"PoolsUpdateFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"poolAddrs\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"aRps\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"shares\",\"type\":\"uint256[]\"}],\"name\":\"PoolsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"poolAddr\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"RewardClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"consensuAddr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Staked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"validator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"contractBalance\",\"type\":\"uint256\"}],\"name\":\"StakingAmountDeductFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"validator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"contractBalance\",\"type\":\"uint256\"}],\"name\":\"StakingAmountTransferFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"consensuAddr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Undelegated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"consensuAddr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Unstaked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"poolAddr\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"debited\",\"type\":\"uint256\"}],\"name\":\"UserRewardUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"ValidatorContractUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"secs\",\"type\":\"uint256\"}],\"name\":\"WaitingSecsToRevokeUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_candidateAdmin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_consensusAddr\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_treasuryAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bridgeOperatorAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_commissionRate\",\"type\":\"uint256\"}],\"name\":\"applyValidatorCandidate\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_consensusAddrs\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_amounts\",\"type\":\"uint256[]\"}],\"name\":\"bulkUndelegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_consensusAddrList\",\"type\":\"address[]\"}],\"name\":\"claimRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"cooldownSecsToUndelegate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensusAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"deductStakingAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_actualDeductingAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensusAddr\",\"type\":\"address\"}],\"name\":\"delegate\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_consensusAddrList\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"_consensusAddrDst\",\"type\":\"address\"}],\"name\":\"delegateRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_pools\",\"type\":\"address[]\"}],\"name\":\"deprecatePools\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_pools\",\"type\":\"address[]\"}],\"name\":\"getManySelfStakings\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_selfStakings\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_poolAddrs\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_userList\",\"type\":\"address[]\"}],\"name\":\"getManyStakingAmounts\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_stakingAmounts\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_poolList\",\"type\":\"address[]\"}],\"name\":\"getManyStakingTotals\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_stakingAmounts\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAdminAddr\",\"type\":\"address\"}],\"name\":\"getPoolAddressOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getReward\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"_poolAddrList\",\"type\":\"address[]\"}],\"name\":\"getRewards\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_rewards\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getStakingAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddr\",\"type\":\"address\"}],\"name\":\"getStakingPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_stakingAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_stakingTotal\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddr\",\"type\":\"address\"}],\"name\":\"getStakingTotal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"__validatorContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"__minValidatorStakingAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"__cooldownSecsToUndelegate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"__waitingSecsToRevoke\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAdminAddr\",\"type\":\"address\"}],\"name\":\"isActivePoolAdmin\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minValidatorStakingAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_consensusAddrs\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_rewards\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_period\",\"type\":\"uint256\"}],\"name\":\"recordRewards\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensusAddrSrc\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_consensusAddrDst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"redelegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensusAddr\",\"type\":\"address\"}],\"name\":\"requestRenounce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensusAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_effectiveDaysOnwards\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_commissionRate\",\"type\":\"uint256\"}],\"name\":\"requestUpdateCommissionRate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_cooldownSecs\",\"type\":\"uint256\"}],\"name\":\"setCooldownSecsToUndelegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"setMinValidatorStakingAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"setValidatorContract\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_secs\",\"type\":\"uint256\"}],\"name\":\"setWaitingSecsToRevoke\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensusAddr\",\"type\":\"address\"}],\"name\":\"stake\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensusAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"undelegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensusAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unstake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validatorContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"waitingSecsToRevoke\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"applyValidatorCandidate(address,address,address,address,uint256)\":{\"details\":\"Proposes a candidate to become a validator. Requirements: - The method caller is able to receive RON. - The treasury is able to receive RON. - The amount is larger than or equal to the minimum validator staking amount `minValidatorStakingAmount()`. Emits the event `PoolApproved`.\",\"params\":{\"_candidateAdmin\":\"the candidate admin will be stored in the validator contract, used for calling function that affects to its candidate, e.g. scheduling maintenance.\"}},\"bulkUndelegate(address[],uint256[])\":{\"details\":\"Bulk unstakes from a list of candidates. Requirements: - The method caller is not the pool admin. Emits the events `Undelegated`.\"},\"claimRewards(address[])\":{\"details\":\"Claims the reward of method caller. Emits the `RewardClaimed` event.\"},\"cooldownSecsToUndelegate()\":{\"details\":\"Returns The cooldown time in seconds to undelegate from the last timestamp (s)he delegated.\"},\"deductStakingAmount(address,uint256)\":{\"details\":\"Deducts from staking amount of the validator `_consensusAddr` for `_amount`. Requirements: - The method caller is validator contract. Emits the event `Unstaked`.\"},\"delegate(address)\":{\"details\":\"Stakes for a validator candidate `_consensusAddr`. Requirements: - The consensus address is a validator candidate. - The method caller is not the pool admin. Emits the `Delegated` event.\"},\"delegateRewards(address[],address)\":{\"details\":\"Claims the rewards and delegates them to the consensus address. Requirements: - The method caller is not the pool admin. - The consensus address `_consensusAddrDst` is a validator candidate. Emits the `RewardClaimed` event and the `Delegated` event.\"},\"deprecatePools(address[])\":{\"details\":\"Deprecates the pool. - Deduct self-staking amount of the pool admin to zero. - Transfer the deducted amount to the pool admin. - Deactivate the pool admin address in the mapping of active pool admins Requirements: - The method caller is validator contract. Emits the event `PoolsDeprecated` and `Unstaked` events. Emits the event `StakingAmountTransferFailed` if the contract cannot transfer RON back to the pool admin.\"},\"getManySelfStakings(address[])\":{\"details\":\"Returns the self-staking amounts of the pools.\"},\"getManyStakingAmounts(address[],address[])\":{\"details\":\"Returns the staking amounts of the users.\"},\"getManyStakingTotals(address[])\":{\"details\":\"Returns the total staking amounts of all users for the pools `_poolAddrs`.\"},\"getPoolAddressOf(address)\":{\"details\":\"Returns the consensus address corresponding to the pool admin.\"},\"getReward(address,address)\":{\"details\":\"Returns the reward amount that user claimable.\"},\"getRewards(address,address[])\":{\"details\":\"Returns the claimable reward of the user `_user`.\"},\"getStakingAmount(address,address)\":{\"details\":\"Returns the staking amount of an user.\"},\"getStakingPool(address)\":{\"details\":\"Returns the staking pool detail.\"},\"getStakingTotal(address)\":{\"details\":\"Returns the total staking amount of all users for a pool.\"},\"initialize(address,uint256,uint256,uint256)\":{\"details\":\"Initializes the contract storage.\"},\"isActivePoolAdmin(address)\":{\"details\":\"Returns whether the `_poolAdminAddr` is currently active.\"},\"minValidatorStakingAmount()\":{\"details\":\"Returns the minimum threshold for being a validator candidate.\"},\"recordRewards(address[],uint256[],uint256)\":{\"details\":\"Records the amount of rewards `_rewards` for the pools `_consensusAddrs`. Requirements: - The method caller is validator contract. Emits the event `PoolsUpdated` once the contract recorded the rewards successfully. Emits the event `PoolsUpdateFailed` once the input array lengths are not equal. Emits the event `PoolsUpdateConflicted` when there are some pools which already updated in the period. Note: This method should be called once at the period ending.\"},\"redelegate(address,address,uint256)\":{\"details\":\"Unstakes an amount of RON from the `_consensusAddrSrc` and stake for `_consensusAddrDst`. Requirements: - The method caller is not the pool admin. - The consensus address `_consensusAddrDst` is a validator candidate. Emits the `Undelegated` event and the `Delegated` event.\"},\"requestRenounce(address)\":{\"details\":\"Renounces being a validator candidate and takes back the delegating/staking amount. Requirements: - The consensus address is a validator candidate. - The method caller is the pool admin.\"},\"requestUpdateCommissionRate(address,uint256,uint256)\":{\"details\":\"Pool admin requests update validator commission rate. The request will be forwarded to the candidate manager contract, and the value is getting updated in {ICandidateManager-execRequestUpdateCommissionRate}. Requirements: - The consensus address is a validator candidate. - The method caller is the pool admin. - The `_effectiveDaysOnwards` must be equal to or larger than the {CandidateManager-_minEffectiveDaysOnwards}. - The `_rate` must be in range of [0_00; 100_00]. Emits the event `CommissionRateUpdated`.\"},\"setCooldownSecsToUndelegate(uint256)\":{\"details\":\"Sets the cooldown time in seconds to undelegate from the last timestamp (s)he delegated. Requirements: - The method caller is admin. Emits the event `CooldownSecsToUndelegateUpdated`.\"},\"setMinValidatorStakingAmount(uint256)\":{\"details\":\"Sets the minimum threshold for being a validator candidate. Requirements: - The method caller is admin. Emits the `MinValidatorStakingAmountUpdated` event.\"},\"setValidatorContract(address)\":{\"details\":\"Sets the validator contract. Requirements: - The method caller is admin. - The new address is a contract. Emits the event `ValidatorContractUpdated`.\"},\"setWaitingSecsToRevoke(uint256)\":{\"details\":\"Sets the number of seconds that a candidate must wait to be revoked. Requirements: - The method caller is admin. Emits the event `WaitingSecsToRevokeUpdated`.\"},\"stake(address)\":{\"details\":\"Self-delegates to the validator candidate `_consensusAddr`. Requirements: - The consensus address is a validator candidate. - The method caller is the pool admin. - The `msg.value` is larger than 0. Emits the event `Staked`.\"},\"undelegate(address,uint256)\":{\"details\":\"Unstakes from a validator candidate `_consensusAddr` for `_amount`. Requirements: - The method caller is not the pool admin. Emits the `Undelegated` event.\"},\"unstake(address,uint256)\":{\"details\":\"Unstakes from the validator candidate `_consensusAddr` for `_amount`. Requirements: - The consensus address is a validator candidate. - The method caller is the pool admin. Emits the event `Unstaked`.\"},\"validatorContract()\":{\"details\":\"Returns the validator contract.\"},\"waitingSecsToRevoke()\":{\"details\":\"Returns the number of seconds that a candidate must wait for the renounce request gets affected.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ronin/staking/Staking.sol\":\"Staking\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x0e9621f60b2faabe65549f7ed0f24e8853a45c1b7990d47e8160e523683f3935\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/extensions/RONTransferHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nabstract contract RONTransferHelper {\\n /**\\n * @dev See `_sendRON`.\\n * Reverts if the recipient does not receive RON.\\n */\\n function _transferRON(address payable _recipient, uint256 _amount) internal {\\n require(_sendRON(_recipient, _amount), \\\"RONTransfer: unable to transfer value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Send `_amount` RON to the address `_recipient`.\\n * Returns whether the recipient receives RON or not.\\n * Reverts once the contract balance is insufficient.\\n *\\n * Note: consider using `ReentrancyGuard` before calling this function.\\n *\\n */\\n function _sendRON(address payable _recipient, uint256 _amount) internal returns (bool _success) {\\n require(address(this).balance >= _amount, \\\"RONTransfer: insufficient balance\\\");\\n return _unsafeSendRON(_recipient, _amount);\\n }\\n\\n /**\\n * @dev Unsafe send `_amount` RON to the address `_recipient`. If the sender's balance is insufficient,\\n * the call does not revert.\\n *\\n * Note:\\n * - Does not assert whether the balance of sender is sufficient.\\n * - Does not assert whether the recipient accepts RON.\\n * - Consider using `ReentrancyGuard` before calling this function.\\n *\\n */\\n function _unsafeSendRON(address payable _recipient, uint256 _amount) internal returns (bool _success) {\\n (_success, ) = _recipient.call{ value: _amount }(\\\"\\\");\\n }\\n}\\n\",\"keccak256\":\"0xd2d20123d75f4d4ca6441a791a3eb1b546b5c8652119ffc8406a11c8ed16529e\",\"license\":\"MIT\"},\"contracts/extensions/collections/HasProxyAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/StorageSlot.sol\\\";\\n\\nabstract contract HasProxyAdmin {\\n // bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n modifier onlyAdmin() {\\n require(msg.sender == _getAdmin(), \\\"HasProxyAdmin: unauthorized sender\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns proxy admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n}\\n\",\"keccak256\":\"0x0c2fcf25290180e8cd733691b113464cdde671dc019e6c343e9eb3e16c6ca24a\",\"license\":\"MIT\"},\"contracts/extensions/collections/HasValidatorContract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./HasProxyAdmin.sol\\\";\\nimport \\\"../../interfaces/collections/IHasValidatorContract.sol\\\";\\nimport \\\"../../interfaces/validator/IRoninValidatorSet.sol\\\";\\n\\ncontract HasValidatorContract is IHasValidatorContract, HasProxyAdmin {\\n IRoninValidatorSet internal _validatorContract;\\n\\n modifier onlyValidatorContract() {\\n require(validatorContract() == msg.sender, \\\"HasValidatorContract: method caller must be validator contract\\\");\\n _;\\n }\\n\\n /**\\n * @inheritdoc IHasValidatorContract\\n */\\n function validatorContract() public view override returns (address) {\\n return address(_validatorContract);\\n }\\n\\n /**\\n * @inheritdoc IHasValidatorContract\\n */\\n function setValidatorContract(address _addr) external override onlyAdmin {\\n require(_addr.code.length > 0, \\\"HasValidatorContract: set to non-contract\\\");\\n _setValidatorContract(_addr);\\n }\\n\\n /**\\n * @dev Sets the validator contract.\\n *\\n * Emits the event `ValidatorContractUpdated`.\\n *\\n */\\n function _setValidatorContract(address _addr) internal {\\n _validatorContract = IRoninValidatorSet(_addr);\\n emit ValidatorContractUpdated(_addr);\\n }\\n}\\n\",\"keccak256\":\"0xfc2ef0f8358960702307626dc4ccbab066c5e0763e04e8a794f0dc4711789bdd\",\"license\":\"MIT\"},\"contracts/interfaces/collections/IHasValidatorContract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface IHasValidatorContract {\\n /// @dev Emitted when the validator contract is updated.\\n event ValidatorContractUpdated(address);\\n\\n /**\\n * @dev Returns the validator contract.\\n */\\n function validatorContract() external view returns (address);\\n\\n /**\\n * @dev Sets the validator contract.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n * - The new address is a contract.\\n *\\n * Emits the event `ValidatorContractUpdated`.\\n *\\n */\\n function setValidatorContract(address) external;\\n}\\n\",\"keccak256\":\"0xb6e39a02969091decbb50633286855c157502a7d15a988e436644b8d419e13d3\",\"license\":\"MIT\"},\"contracts/interfaces/consumers/PeriodWrapperConsumer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface PeriodWrapperConsumer {\\n struct PeriodWrapper {\\n // Inner value.\\n uint256 inner;\\n // Last period number that the info updated.\\n uint256 lastPeriod;\\n }\\n}\\n\",\"keccak256\":\"0xb6777e3c364306eb8d5355583c1aca44de9d351cb40ddf1cea832206d4aad272\",\"license\":\"MIT\"},\"contracts/interfaces/staking/IBaseStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface IBaseStaking {\\n struct PoolDetail {\\n // Address of the pool i.e. consensus address of the validator\\n address addr;\\n // Pool admin address\\n address admin;\\n // Self-staking amount\\n uint256 stakingAmount;\\n // Total number of RON staking for the pool\\n uint256 stakingTotal;\\n // Mapping from delegator => delegating amount\\n mapping(address => uint256) delegatingAmount;\\n // Mapping from delegator => the last timestamp that delegator staked\\n mapping(address => uint256) lastDelegatingTimestamp;\\n }\\n\\n /// @dev Emitted when the minium number of seconds to undelegate is updated.\\n event CooldownSecsToUndelegateUpdated(uint256 minSecs);\\n /// @dev Emitted when the number of seconds that a candidate must wait to be revoked.\\n event WaitingSecsToRevokeUpdated(uint256 secs);\\n\\n /**\\n * @dev Returns whether the `_poolAdminAddr` is currently active.\\n */\\n function isActivePoolAdmin(address _poolAdminAddr) external view returns (bool);\\n\\n /**\\n * @dev Returns the consensus address corresponding to the pool admin.\\n */\\n function getPoolAddressOf(address _poolAdminAddr) external view returns (address);\\n\\n /**\\n * @dev Returns The cooldown time in seconds to undelegate from the last timestamp (s)he delegated.\\n */\\n function cooldownSecsToUndelegate() external view returns (uint256);\\n\\n /**\\n * @dev Returns the number of seconds that a candidate must wait for the renounce request gets affected.\\n */\\n function waitingSecsToRevoke() external view returns (uint256);\\n\\n /**\\n * @dev Sets the cooldown time in seconds to undelegate from the last timestamp (s)he delegated.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n *\\n * Emits the event `CooldownSecsToUndelegateUpdated`.\\n *\\n */\\n function setCooldownSecsToUndelegate(uint256 _cooldownSecs) external;\\n\\n /**\\n * @dev Sets the number of seconds that a candidate must wait to be revoked.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n *\\n * Emits the event `WaitingSecsToRevokeUpdated`.\\n *\\n */\\n function setWaitingSecsToRevoke(uint256 _secs) external;\\n}\\n\",\"keccak256\":\"0xf1e65eabb1dfecf8330bf57d286e27f92dddb0d45c90c5b92cc05f28b0090f14\",\"license\":\"MIT\"},\"contracts/interfaces/staking/ICandidateStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"./IRewardPool.sol\\\";\\n\\ninterface ICandidateStaking is IRewardPool {\\n /// @dev Emitted when the minimum staking amount for being a validator is updated.\\n event MinValidatorStakingAmountUpdated(uint256 threshold);\\n\\n /// @dev Emitted when the pool admin staked for themself.\\n event Staked(address indexed consensuAddr, uint256 amount);\\n /// @dev Emitted when the pool admin unstaked the amount of RON from themself.\\n event Unstaked(address indexed consensuAddr, uint256 amount);\\n\\n /// @dev Emitted when the validator pool is approved.\\n event PoolApproved(address indexed validator, address indexed admin);\\n /// @dev Emitted when the validator pool is deprecated.\\n event PoolsDeprecated(address[] validator);\\n /// @dev Emitted when the staking amount transfer failed.\\n event StakingAmountTransferFailed(\\n address indexed validator,\\n address indexed admin,\\n uint256 amount,\\n uint256 contractBalance\\n );\\n /// @dev Emitted when the staking amount deducted failed, e.g. when the validator gets slashed.\\n event StakingAmountDeductFailed(\\n address indexed validator,\\n address indexed recipient,\\n uint256 amount,\\n uint256 contractBalance\\n );\\n\\n /**\\n * @dev Returns the minimum threshold for being a validator candidate.\\n */\\n function minValidatorStakingAmount() external view returns (uint256);\\n\\n /**\\n * @dev Sets the minimum threshold for being a validator candidate.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n *\\n * Emits the `MinValidatorStakingAmountUpdated` event.\\n *\\n */\\n function setMinValidatorStakingAmount(uint256) external;\\n\\n /**\\n * @dev Proposes a candidate to become a validator.\\n *\\n * Requirements:\\n * - The method caller is able to receive RON.\\n * - The treasury is able to receive RON.\\n * - The amount is larger than or equal to the minimum validator staking amount `minValidatorStakingAmount()`.\\n *\\n * Emits the event `PoolApproved`.\\n *\\n * @param _candidateAdmin the candidate admin will be stored in the validator contract, used for calling function that affects\\n * to its candidate, e.g. scheduling maintenance.\\n *\\n */\\n function applyValidatorCandidate(\\n address _candidateAdmin,\\n address _consensusAddr,\\n address payable _treasuryAddr,\\n address _bridgeOperatorAddr,\\n uint256 _commissionRate\\n ) external payable;\\n\\n /**\\n * @dev Deprecates the pool.\\n * - Deduct self-staking amount of the pool admin to zero.\\n * - Transfer the deducted amount to the pool admin.\\n * - Deactivate the pool admin address in the mapping of active pool admins\\n *\\n * Requirements:\\n * - The method caller is validator contract.\\n *\\n * Emits the event `PoolsDeprecated` and `Unstaked` events.\\n * Emits the event `StakingAmountTransferFailed` if the contract cannot transfer RON back to the pool admin.\\n *\\n */\\n function deprecatePools(address[] calldata _pools) external;\\n\\n /**\\n * @dev Self-delegates to the validator candidate `_consensusAddr`.\\n *\\n * Requirements:\\n * - The consensus address is a validator candidate.\\n * - The method caller is the pool admin.\\n * - The `msg.value` is larger than 0.\\n *\\n * Emits the event `Staked`.\\n *\\n */\\n function stake(address _consensusAddr) external payable;\\n\\n /**\\n * @dev Unstakes from the validator candidate `_consensusAddr` for `_amount`.\\n *\\n * Requirements:\\n * - The consensus address is a validator candidate.\\n * - The method caller is the pool admin.\\n *\\n * Emits the event `Unstaked`.\\n *\\n */\\n function unstake(address _consensusAddr, uint256 _amount) external;\\n\\n /**\\n * @dev Pool admin requests update validator commission rate. The request will be forwarded to the candidate manager\\n * contract, and the value is getting updated in {ICandidateManager-execRequestUpdateCommissionRate}.\\n *\\n * Requirements:\\n * - The consensus address is a validator candidate.\\n * - The method caller is the pool admin.\\n * - The `_effectiveDaysOnwards` must be equal to or larger than the {CandidateManager-_minEffectiveDaysOnwards}.\\n * - The `_rate` must be in range of [0_00; 100_00].\\n *\\n * Emits the event `CommissionRateUpdated`.\\n *\\n */\\n function requestUpdateCommissionRate(\\n address _consensusAddr,\\n uint256 _effectiveDaysOnwards,\\n uint256 _commissionRate\\n ) external;\\n\\n /**\\n * @dev Renounces being a validator candidate and takes back the delegating/staking amount.\\n *\\n * Requirements:\\n * - The consensus address is a validator candidate.\\n * - The method caller is the pool admin.\\n *\\n */\\n function requestRenounce(address _consensusAddr) external;\\n}\\n\",\"keccak256\":\"0x8ced5bc423094821a203e7100076868ca41a7176e0ebc0fd09d1fd5f6c5fac8a\",\"license\":\"MIT\"},\"contracts/interfaces/staking/IDelegatorStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"./IRewardPool.sol\\\";\\n\\ninterface IDelegatorStaking is IRewardPool {\\n /// @dev Emitted when the delegator staked for a validator candidate.\\n event Delegated(address indexed delegator, address indexed consensuAddr, uint256 amount);\\n /// @dev Emitted when the delegator unstaked from a validator candidate.\\n event Undelegated(address indexed delegator, address indexed consensuAddr, uint256 amount);\\n\\n /**\\n * @dev Stakes for a validator candidate `_consensusAddr`.\\n *\\n * Requirements:\\n * - The consensus address is a validator candidate.\\n * - The method caller is not the pool admin.\\n *\\n * Emits the `Delegated` event.\\n *\\n */\\n function delegate(address _consensusAddr) external payable;\\n\\n /**\\n * @dev Unstakes from a validator candidate `_consensusAddr` for `_amount`.\\n *\\n * Requirements:\\n * - The method caller is not the pool admin.\\n *\\n * Emits the `Undelegated` event.\\n *\\n */\\n function undelegate(address _consensusAddr, uint256 _amount) external;\\n\\n /**\\n * @dev Bulk unstakes from a list of candidates.\\n *\\n * Requirements:\\n * - The method caller is not the pool admin.\\n *\\n * Emits the events `Undelegated`.\\n *\\n */\\n function bulkUndelegate(address[] calldata _consensusAddrs, uint256[] calldata _amounts) external;\\n\\n /**\\n * @dev Unstakes an amount of RON from the `_consensusAddrSrc` and stake for `_consensusAddrDst`.\\n *\\n * Requirements:\\n * - The method caller is not the pool admin.\\n * - The consensus address `_consensusAddrDst` is a validator candidate.\\n *\\n * Emits the `Undelegated` event and the `Delegated` event.\\n *\\n */\\n function redelegate(\\n address _consensusAddrSrc,\\n address _consensusAddrDst,\\n uint256 _amount\\n ) external;\\n\\n /**\\n * @dev Returns the claimable reward of the user `_user`.\\n */\\n function getRewards(address _user, address[] calldata _poolAddrList)\\n external\\n view\\n returns (uint256[] memory _rewards);\\n\\n /**\\n * @dev Claims the reward of method caller.\\n *\\n * Emits the `RewardClaimed` event.\\n *\\n */\\n function claimRewards(address[] calldata _consensusAddrList) external returns (uint256 _amount);\\n\\n /**\\n * @dev Claims the rewards and delegates them to the consensus address.\\n *\\n * Requirements:\\n * - The method caller is not the pool admin.\\n * - The consensus address `_consensusAddrDst` is a validator candidate.\\n *\\n * Emits the `RewardClaimed` event and the `Delegated` event.\\n *\\n */\\n function delegateRewards(address[] calldata _consensusAddrList, address _consensusAddrDst)\\n external\\n returns (uint256 _amount);\\n}\\n\",\"keccak256\":\"0xc937036bcda0a4632af4937c514230a7b301d1f42959bfb00c377cb76f3f61bc\",\"license\":\"MIT\"},\"contracts/interfaces/staking/IRewardPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"../../interfaces/consumers/PeriodWrapperConsumer.sol\\\";\\n\\ninterface IRewardPool is PeriodWrapperConsumer {\\n struct UserRewardFields {\\n // Recorded reward amount.\\n uint256 debited;\\n // The last accumulated of the amount rewards per share (one unit staking) that the info updated.\\n uint256 aRps;\\n // Min staking amount in the period.\\n uint256 minAmount;\\n // Last period number that the info updated.\\n uint256 lastPeriod;\\n }\\n\\n struct PoolFields {\\n // Accumulated of the amount rewards per share (one unit staking).\\n uint256 aRps;\\n // The staking total to share reward of the current period.\\n PeriodWrapper shares;\\n }\\n\\n /// @dev Emitted when the fields to calculate pending reward for the user is updated.\\n event UserRewardUpdated(address indexed poolAddr, address indexed user, uint256 debited);\\n /// @dev Emitted when the user claimed their reward\\n event RewardClaimed(address indexed poolAddr, address indexed user, uint256 amount);\\n\\n /// @dev Emitted when the pool shares are updated\\n event PoolSharesUpdated(uint256 indexed period, address indexed poolAddr, uint256 shares);\\n /// @dev Emitted when the pools are updated\\n event PoolsUpdated(uint256 indexed period, address[] poolAddrs, uint256[] aRps, uint256[] shares);\\n /// @dev Emitted when the contract fails when updating the pools\\n event PoolsUpdateFailed(uint256 indexed period, address[] poolAddrs, uint256[] rewards);\\n /// @dev Emitted when the contract fails when updating the pools that already set\\n event PoolsUpdateConflicted(uint256 indexed period, address[] poolAddrs);\\n\\n /**\\n * @dev Returns the reward amount that user claimable.\\n */\\n function getReward(address _poolAddr, address _user) external view returns (uint256);\\n\\n /**\\n * @dev Returns the staking amount of an user.\\n */\\n function getStakingAmount(address _poolAddr, address _user) external view returns (uint256);\\n\\n /**\\n * @dev Returns the staking amounts of the users.\\n */\\n function getManyStakingAmounts(address[] calldata _poolAddrs, address[] calldata _userList)\\n external\\n view\\n returns (uint256[] memory);\\n\\n /**\\n * @dev Returns the total staking amount of all users for a pool.\\n */\\n function getStakingTotal(address _poolAddr) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total staking amounts of all users for the pools `_poolAddrs`.\\n */\\n function getManyStakingTotals(address[] calldata _poolAddrs) external view returns (uint256[] memory);\\n}\\n\",\"keccak256\":\"0x8a4d4ab84f0b343cea84b8e86f90f4b9286051a166e348f5ef6c7d2d2c2af09f\",\"license\":\"MIT\"},\"contracts/interfaces/staking/IStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"./IBaseStaking.sol\\\";\\nimport \\\"./ICandidateStaking.sol\\\";\\nimport \\\"./IDelegatorStaking.sol\\\";\\n\\ninterface IStaking is IRewardPool, IBaseStaking, ICandidateStaking, IDelegatorStaking {\\n /**\\n * @dev Records the amount of rewards `_rewards` for the pools `_consensusAddrs`.\\n *\\n * Requirements:\\n * - The method caller is validator contract.\\n *\\n * Emits the event `PoolsUpdated` once the contract recorded the rewards successfully.\\n * Emits the event `PoolsUpdateFailed` once the input array lengths are not equal.\\n * Emits the event `PoolsUpdateConflicted` when there are some pools which already updated in the period.\\n *\\n * Note: This method should be called once at the period ending.\\n *\\n */\\n function recordRewards(\\n address[] calldata _consensusAddrs,\\n uint256[] calldata _rewards,\\n uint256 _period\\n ) external payable;\\n\\n /**\\n * @dev Deducts from staking amount of the validator `_consensusAddr` for `_amount`.\\n *\\n * Requirements:\\n * - The method caller is validator contract.\\n *\\n * Emits the event `Unstaked`.\\n *\\n */\\n function deductStakingAmount(address _consensusAddr, uint256 _amount)\\n external\\n returns (uint256 _actualDeductingAmount);\\n\\n /**\\n * @dev Returns the staking pool detail.\\n */\\n function getStakingPool(address)\\n external\\n view\\n returns (\\n address _admin,\\n uint256 _stakingAmount,\\n uint256 _stakingTotal\\n );\\n\\n /**\\n * @dev Returns the self-staking amounts of the pools.\\n */\\n function getManySelfStakings(address[] calldata) external view returns (uint256[] memory);\\n}\\n\",\"keccak256\":\"0x84a3f7dfb1d291808514207da26c29fba58479a780d8f955e1cf5ea413fbba83\",\"license\":\"MIT\"},\"contracts/interfaces/validator/ICandidateManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface ICandidateManager {\\n struct ValidatorCandidate {\\n // Admin of the candidate\\n address admin;\\n // Address of the validator that produces block, e.g. block.coinbase. This is so-called validator address.\\n address consensusAddr;\\n // Address that receives mining reward of the validator\\n address payable treasuryAddr;\\n // Address of the bridge operator corresponding to the candidate\\n address bridgeOperatorAddr;\\n // The percentage of reward that validators can be received, the rest goes to the delegators.\\n // Values in range [0; 100_00] stands for 0-100%\\n uint256 commissionRate;\\n // The timestamp that scheduled to revoke the candidate (no schedule=0)\\n uint256 revokingTimestamp;\\n // The deadline that the candidate must top up staking amount to keep it larger than or equal to the threshold (no deadline=0)\\n uint256 topupDeadline;\\n }\\n\\n struct CommissionSchedule {\\n // The timestamp that the commission schedule gets affected (no schedule=0).\\n uint256 effectiveTimestamp;\\n // The new commission rate. Value is in range [0; 100_00], stands for 0-100%\\n uint256 commissionRate;\\n }\\n\\n /// @dev Emitted when the maximum number of validator candidates is updated.\\n event MaxValidatorCandidateUpdated(uint256 threshold);\\n /// @dev Emitted when the min offset to the effective date of commission rate change is updated.\\n event MinEffectiveDaysOnwardsUpdated(uint256 numOfDays);\\n /// @dev Emitted when the validator candidate is granted.\\n event CandidateGranted(\\n address indexed consensusAddr,\\n address indexed treasuryAddr,\\n address indexed admin,\\n address bridgeOperator\\n );\\n /// @dev Emitted when the revoking timestamp of a candidate is updated.\\n event CandidateRevokingTimestampUpdated(address indexed consensusAddr, uint256 revokingTimestamp);\\n /// @dev Emitted when the topup deadline of a candidate is updated.\\n event CandidateTopupDeadlineUpdated(address indexed consensusAddr, uint256 topupDeadline);\\n /// @dev Emitted when the validator candidate is revoked.\\n event CandidatesRevoked(address[] consensusAddrs);\\n\\n /// @dev Emitted when a schedule for updating commission rate is set.\\n event CommissionRateUpdateScheduled(address indexed consensusAddr, uint256 effectiveTimestamp, uint256 rate);\\n /// @dev Emitted when the commission rate of a validator is updated.\\n event CommissionRateUpdated(address indexed consensusAddr, uint256 rate);\\n\\n /**\\n * @dev Returns the maximum number of validator candidate.\\n */\\n function maxValidatorCandidate() external view returns (uint256);\\n\\n /**\\n * @dev Returns the minimum number of days to the effective date of commission rate change.\\n */\\n function minEffectiveDaysOnwards() external view returns (uint256);\\n\\n /**\\n * @dev Sets the maximum number of validator candidate.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n *\\n * Emits the `MaxValidatorCandidateUpdated` event.\\n *\\n */\\n function setMaxValidatorCandidate(uint256) external;\\n\\n /**\\n * @dev Sets the minimum number of days to the effective date of commision rate change.\\n *\\n * Requirements:\\n * - The method caller is admin.\\n *\\n * Emits the `MinEffectiveDaysOnwardsUpdated` event.\\n *\\n */\\n function setMinEffectiveDaysOnwards(uint256 _numOfDays) external;\\n\\n /**\\n * @dev Grants a validator candidate.\\n *\\n * Requirements:\\n * - The method caller is staking contract.\\n *\\n * Emits the event `CandidateGranted`.\\n *\\n */\\n function grantValidatorCandidate(\\n address _admin,\\n address _consensusAddr,\\n address payable _treasuryAddr,\\n address _bridgeOperatorAddr,\\n uint256 _commissionRate\\n ) external;\\n\\n /**\\n * @dev Requests to revoke a validator candidate in next `_secsLeft` seconds.\\n *\\n * Requirements:\\n * - The method caller is staking contract.\\n *\\n * Emits the event `CandidateRevokingTimestampUpdated`.\\n *\\n */\\n function requestRevokeCandidate(address, uint256 _secsLeft) external;\\n\\n /**\\n * @dev Fallback function of `CandidateStaking-requestUpdateCommissionRate`.\\n *\\n * Requirements:\\n * - The method caller is the staking contract.\\n * - The `_effectiveTimestamp` must be the beginning of a UTC day, and at least from 7 days onwards\\n * - The `_rate` must be in range of [0_00; 100_00].\\n *\\n * Emits the event `CommissionRateUpdateScheduled`.\\n *\\n */\\n function execRequestUpdateCommissionRate(\\n address _consensusAddr,\\n uint256 _effectiveTimestamp,\\n uint256 _rate\\n ) external;\\n\\n /**\\n * @dev Returns whether the address is a validator (candidate).\\n */\\n function isValidatorCandidate(address _addr) external view returns (bool);\\n\\n /**\\n * @dev Returns the validator candidate.\\n */\\n function getValidatorCandidates() external view returns (address[] memory);\\n\\n /**\\n * @dev Returns all candidate info.\\n */\\n function getCandidateInfos() external view returns (ValidatorCandidate[] memory);\\n\\n /**\\n * @dev Returns the info of a candidate.\\n */\\n function getCandidateInfo(address _candidate) external view returns (ValidatorCandidate memory);\\n\\n /**\\n * @dev Returns whether the address is the candidate admin.\\n */\\n function isCandidateAdmin(address _candidate, address _admin) external view returns (bool);\\n\\n /**\\n * @dev Returns the schedule of changing commission rate of a candidate address.\\n */\\n function getCommissionChangeSchedule(address _candidate) external view returns (CommissionSchedule memory);\\n}\\n\",\"keccak256\":\"0xacfc4038d51b7746d66351009c6f25e277d45eafd23eb057441ed6884f91dd19\",\"license\":\"MIT\"},\"contracts/interfaces/validator/ICoinbaseExecution.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"./ISlashingExecution.sol\\\";\\n\\ninterface ICoinbaseExecution is ISlashingExecution {\\n enum BlockRewardDeprecatedType {\\n UNKNOWN,\\n UNAVAILABILITY,\\n AFTER_BAILOUT\\n }\\n\\n /// @dev Emitted when the validator set is updated\\n event ValidatorSetUpdated(uint256 indexed period, address[] consensusAddrs);\\n /// @dev Emitted when the bridge operator set is updated, to mirror the in-jail and maintaining status of the validator.\\n event BlockProducerSetUpdated(uint256 indexed period, address[] consensusAddrs);\\n /// @dev Emitted when the bridge operator set is updated.\\n event BridgeOperatorSetUpdated(uint256 indexed period, address[] bridgeOperators);\\n\\n /// @dev Emitted when the reward of the block producer is deprecated.\\n event BlockRewardDeprecated(\\n address indexed coinbaseAddr,\\n uint256 rewardAmount,\\n BlockRewardDeprecatedType deprecatedType\\n );\\n /// @dev Emitted when the block reward is submitted.\\n event BlockRewardSubmitted(address indexed coinbaseAddr, uint256 submittedAmount, uint256 bonusAmount);\\n\\n /// @dev Emitted when the block producer reward is distributed.\\n event MiningRewardDistributed(address indexed consensusAddr, address indexed recipient, uint256 amount);\\n /// @dev Emitted when the contract fails when distributing the block producer reward.\\n event MiningRewardDistributionFailed(\\n address indexed consensusAddr,\\n address indexed recipient,\\n uint256 amount,\\n uint256 contractBalance\\n );\\n\\n /// @dev Emitted when the bridge operator reward is distributed.\\n event BridgeOperatorRewardDistributed(\\n address indexed consensusAddr,\\n address indexed bridgeOperator,\\n address indexed recipientAddr,\\n uint256 amount\\n );\\n /// @dev Emitted when the contract fails when distributing the bridge operator reward.\\n event BridgeOperatorRewardDistributionFailed(\\n address indexed consensusAddr,\\n address indexed bridgeOperator,\\n address indexed recipient,\\n uint256 amount,\\n uint256 contractBalance\\n );\\n\\n /// @dev Emitted when the amount of RON reward is distributed to staking contract.\\n event StakingRewardDistributed(uint256 amount);\\n /// @dev Emitted when the contracts fails when distributing the amount of RON to the staking contract.\\n event StakingRewardDistributionFailed(uint256 amount, uint256 contractBalance);\\n\\n /// @dev Emitted when the epoch is wrapped up.\\n event WrappedUpEpoch(uint256 indexed periodNumber, uint256 indexed epochNumber, bool periodEnding);\\n\\n /**\\n * @dev Submits reward of the current block.\\n *\\n * Requirements:\\n * - The method caller is coinbase.\\n *\\n * Emits the event `MiningRewardDeprecated` if the coinbase is slashed or no longer be a block producer.\\n * Emits the event `BlockRewardSubmitted` for the valid call.\\n *\\n */\\n function submitBlockReward() external payable;\\n\\n /**\\n * @dev Wraps up the current epoch.\\n *\\n * Requirements:\\n * - The method must be called when the current epoch is ending.\\n * - The epoch is not wrapped yet.\\n * - The method caller is coinbase.\\n *\\n * Emits the event `MiningRewardDistributed` when some validator has reward distributed.\\n * Emits the event `StakingRewardDistributed` when some staking pool has reward distributed.\\n * Emits the event `BlockProducerSetUpdated` when the epoch is wrapped up.\\n * Emits the event `BridgeOperatorSetUpdated` when the epoch is wrapped up at period ending.\\n * Emits the event `ValidatorSetUpdated` when the epoch is wrapped up at period ending, and the validator set gets updated.\\n * Emits the event `WrappedUpEpoch`.\\n *\\n */\\n function wrapUpEpoch() external payable;\\n}\\n\",\"keccak256\":\"0xd0aef1d05e99c82fd733c97a45f3a999898c4ded0cace2cb901864e2ddc3904a\",\"license\":\"MIT\"},\"contracts/interfaces/validator/IRoninValidatorSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"./ICandidateManager.sol\\\";\\nimport \\\"./info-fragments/ICommonInfo.sol\\\";\\nimport \\\"./ICoinbaseExecution.sol\\\";\\nimport \\\"./ISlashingExecution.sol\\\";\\n\\ninterface IRoninValidatorSet is ICandidateManager, ICommonInfo, ISlashingExecution, ICoinbaseExecution {}\\n\",\"keccak256\":\"0x2475cf9c7007277ddfeade823196d0913a6d5c3e3fc9a1a10800734c0fdef062\",\"license\":\"MIT\"},\"contracts/interfaces/validator/ISlashingExecution.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface ISlashingExecution {\\n /// @dev Emitted when the validator is punished.\\n event ValidatorPunished(\\n address indexed consensusAddr,\\n uint256 indexed period,\\n uint256 jailedUntil,\\n uint256 deductedStakingAmount,\\n bool blockProducerRewardDeprecated,\\n bool bridgeOperatorRewardDeprecated\\n );\\n /// @dev Emitted when the validator get out of jail by bailout.\\n event ValidatorUnjailed(address indexed validator, uint256 period);\\n\\n /**\\n * @dev Finalize the slash request from slash indicator contract.\\n *\\n * Requirements:\\n * - The method caller is slash indicator contract.\\n *\\n * Emits the event `ValidatorPunished`.\\n *\\n */\\n function execSlash(\\n address _validatorAddr,\\n uint256 _newJailedUntil,\\n uint256 _slashAmount\\n ) external;\\n\\n /**\\n * @dev Finalize the bailout request from slash indicator contract.\\n *\\n * Requirements:\\n * - The method caller is slash indicator contract.\\n *\\n * Emits the event `ValidatorUnjailed`.\\n *\\n */\\n function execBailOut(address _validatorAddr, uint256 _period) external;\\n}\\n\",\"keccak256\":\"0xdeb929875d06c5dfb8562029ccc2922e1c5238f2dc67c8c61acad614f5fe1e28\",\"license\":\"MIT\"},\"contracts/interfaces/validator/info-fragments/ICommonInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"./IJailingInfo.sol\\\";\\nimport \\\"./ITimingInfo.sol\\\";\\nimport \\\"./IValidatorInfo.sol\\\";\\n\\ninterface ICommonInfo is ITimingInfo, IJailingInfo, IValidatorInfo {\\n /// @dev Emitted when the deprecated reward is withdrawn.\\n event DeprecatedRewardRecycled(address indexed recipientAddr, uint256 amount);\\n /// @dev Emitted when the deprecated reward withdrawal is failed\\n event DeprecatedRewardRecycleFailed(address indexed recipientAddr, uint256 amount, uint256 balance);\\n\\n /**\\n * @dev Returns the total deprecated reward, which includes reward that is not sent for slashed validators and unsastified bridge operators\\n */\\n function totalDeprecatedReward() external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x33a52025305948a8e71d32317e4cdb2cf779afc3bcdb5bcbd72df5e1513f449f\",\"license\":\"MIT\"},\"contracts/interfaces/validator/info-fragments/IJailingInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface IJailingInfo {\\n /**\\n * @dev Returns whether the validator are put in jail (cannot join the set of validators) during the current period.\\n */\\n function checkJailed(address) external view returns (bool);\\n\\n /**\\n * @dev Returns whether the validator are put in jail and the number of block and epoch that he still is in the jail.\\n */\\n function getJailedTimeLeft(address _addr)\\n external\\n view\\n returns (\\n bool isJailed_,\\n uint256 blockLeft_,\\n uint256 epochLeft_\\n );\\n\\n /**\\n * @dev Returns whether the validator are put in jail (cannot join the set of validators) at a specific block.\\n */\\n function checkJailedAtBlock(address _addr, uint256 _blockNum) external view returns (bool);\\n\\n /**\\n * @dev Returns whether the validator are put in jail at a specific block and the number of block and epoch that he still is in the jail.\\n */\\n function getJailedTimeLeftAtBlock(address _addr, uint256 _blockNum)\\n external\\n view\\n returns (\\n bool isJailed_,\\n uint256 blockLeft_,\\n uint256 epochLeft_\\n );\\n\\n /**\\n * @dev Returns whether the validators are put in jail (cannot join the set of validators) during the current period.\\n */\\n function checkManyJailed(address[] calldata) external view returns (bool[] memory);\\n\\n /**\\n * @dev Returns whether the incoming reward of the block producers are deprecated during the current period.\\n */\\n function checkMiningRewardDeprecated(address[] calldata _blockProducers) external view returns (bool[] memory);\\n\\n /**\\n * @dev Returns whether the incoming reward of the block producers are deprecated during a specific period.\\n */\\n function checkMiningRewardDeprecatedAtPeriod(address[] calldata _blockProducers, uint256 _period)\\n external\\n view\\n returns (bool[] memory);\\n}\\n\",\"keccak256\":\"0x310f321625fac8b7dbabfdad36e82b960b0b1f7bf0e5b70b763e45438b8a8d30\",\"license\":\"MIT\"},\"contracts/interfaces/validator/info-fragments/ITimingInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface ITimingInfo {\\n /**\\n * @dev Returns the block that validator set was updated.\\n */\\n function getLastUpdatedBlock() external view returns (uint256);\\n\\n /**\\n * @dev Returns the number of blocks in a epoch.\\n */\\n function numberOfBlocksInEpoch() external view returns (uint256 _numberOfBlocks);\\n\\n /**\\n * @dev Returns the epoch index from the block number.\\n */\\n function epochOf(uint256 _block) external view returns (uint256);\\n\\n /**\\n * @dev Returns whether the epoch ending is at the block number `_block`.\\n */\\n function epochEndingAt(uint256 _block) external view returns (bool);\\n\\n /**\\n * @dev Tries to get the period index from the epoch number.\\n */\\n function tryGetPeriodOfEpoch(uint256 _epoch) external view returns (bool _filled, uint256 _periodNumber);\\n\\n /**\\n * @dev Returns whether the period ending at the current block number.\\n */\\n function isPeriodEnding() external view returns (bool);\\n\\n /**\\n * @dev Returns the period index from the current block.\\n */\\n function currentPeriod() external view returns (uint256);\\n\\n /**\\n * @dev Returns the block number that the current period starts at.\\n */\\n function currentPeriodStartAtBlock() external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x77b86a68149389fed0eb0c5b8d56f278d3bd103ba64f504697d709b24c3212d5\",\"license\":\"MIT\"},\"contracts/interfaces/validator/info-fragments/IValidatorInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\ninterface IValidatorInfo {\\n /// @dev Emitted when the number of max validator is updated\\n event MaxValidatorNumberUpdated(uint256);\\n /// @dev Emitted when the number of reserved slots for prioritized validators is updated\\n event MaxPrioritizedValidatorNumberUpdated(uint256);\\n\\n /**\\n * @dev Returns the maximum number of validators in the epoch\\n */\\n function maxValidatorNumber() external view returns (uint256 _maximumValidatorNumber);\\n\\n /**\\n * @dev Returns the number of reserved slots for prioritized validators\\n */\\n function maxPrioritizedValidatorNumber() external view returns (uint256 _maximumPrioritizedValidatorNumber);\\n\\n /**\\n * @dev Returns the current validator list.\\n */\\n function getValidators() external view returns (address[] memory);\\n\\n /**\\n * @dev Returns whether the address is either a bridge operator or a block producer.\\n */\\n function isValidator(address _addr) external view returns (bool);\\n\\n /**\\n * @dev Returns the current block producer list.\\n */\\n function getBlockProducers() external view returns (address[] memory);\\n\\n /**\\n * @dev Returns whether the address is block producer or not.\\n */\\n function isBlockProducer(address _addr) external view returns (bool);\\n\\n /**\\n * @dev Returns total numbers of the block producers.\\n */\\n function totalBlockProducers() external view returns (uint256);\\n\\n /**\\n * @dev Returns the current bridge operator list.\\n */\\n function getBridgeOperators() external view returns (address[] memory);\\n\\n /**\\n * @dev Returns whether the address is bridge operator or not.\\n */\\n function isBridgeOperator(address _addr) external view returns (bool);\\n\\n /**\\n * @dev Returns total numbers of the bridge operators.\\n */\\n function totalBridgeOperators() external view returns (uint256);\\n\\n /**\\n * @dev Updates the max validator number\\n *\\n * Requirements:\\n * - The method caller is admin\\n *\\n * Emits the event `MaxValidatorNumberUpdated`\\n *\\n */\\n function setMaxValidatorNumber(uint256 _maxValidatorNumber) external;\\n\\n /**\\n * @dev Updates the number of reserved slots for prioritized validators\\n *\\n * Requirements:\\n * - The method caller is admin\\n *\\n * Emits the event `MaxPrioritizedValidatorNumberUpdated`\\n *\\n */\\n function setMaxPrioritizedValidatorNumber(uint256 _maxPrioritizedValidatorNumber) external;\\n}\\n\",\"keccak256\":\"0xf7f30bacc63b2e4e9548c83e45eac727eeafa46e60312f936bf189480e413323\",\"license\":\"MIT\"},\"contracts/libraries/AddressArrayUtils.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\n\\npragma solidity ^0.8.0;\\n\\nlibrary AddressArrayUtils {\\n /**\\n * Returns whether or not there's a duplicate. Runs in O(n^2).\\n * @param A Array to search\\n * @return Returns true if duplicate, false otherwise\\n */\\n function hasDuplicate(address[] memory A) internal pure returns (bool) {\\n if (A.length == 0) {\\n return false;\\n }\\n for (uint256 i = 0; i < A.length - 1; i++) {\\n for (uint256 j = i + 1; j < A.length; j++) {\\n if (A[i] == A[j]) {\\n return true;\\n }\\n }\\n }\\n return false;\\n }\\n}\\n\",\"keccak256\":\"0xc64f39980a5f980a3a87b3e4c692e0dd4848950a568cb5a24c39c6f99080c864\",\"license\":\"UNLICENSED\"},\"contracts/libraries/Math.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\n\\npragma solidity ^0.8.0;\\n\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns whether the number `c` is in range of [a; b].\\n */\\n function inRange(\\n uint256 c,\\n uint256 a,\\n uint256 b\\n ) internal pure returns (bool) {\\n return a <= c && c <= b;\\n }\\n\\n /**\\n * @dev Returns whether two inclusive ranges [x1;x2] and [y1;y2] overlap.\\n */\\n function twoRangeOverlap(\\n uint256 x1,\\n uint256 x2,\\n uint256 y1,\\n uint256 y2\\n ) internal pure returns (bool) {\\n return x1 <= y2 && y1 <= x2;\\n }\\n\\n /**\\n * @dev Returns value of a + b; in case result is larger than upperbound, upperbound is returned.\\n */\\n function addWithUpperbound(\\n uint256 a,\\n uint256 b,\\n uint256 upperbound\\n ) internal pure returns (uint256) {\\n return min(a + b, upperbound);\\n }\\n\\n /**\\n * @dev Returns value of a - b; in case of negative result, 0 is returned.\\n */\\n function subNonNegative(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a - min(a, b);\\n }\\n}\\n\",\"keccak256\":\"0xa9e2a3ad43d7999a3cdbfb040b0f2dec282eae91ff8fe6ad26fdd19087121ce7\",\"license\":\"UNLICENSED\"},\"contracts/ronin/staking/BaseStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport \\\"../../extensions/RONTransferHelper.sol\\\";\\nimport \\\"../../extensions/collections/HasValidatorContract.sol\\\";\\nimport \\\"../../interfaces/staking/IBaseStaking.sol\\\";\\nimport \\\"../../libraries/Math.sol\\\";\\nimport \\\"./RewardCalculation.sol\\\";\\n\\nabstract contract BaseStaking is\\n RONTransferHelper,\\n ReentrancyGuard,\\n RewardCalculation,\\n HasValidatorContract,\\n IBaseStaking\\n{\\n /// @dev Mapping from pool address => staking pool detail\\n mapping(address => PoolDetail) internal _stakingPool;\\n\\n /// @dev The cooldown time in seconds to undelegate from the last timestamp (s)he delegated.\\n uint256 internal _cooldownSecsToUndelegate;\\n /// @dev The number of seconds that a candidate must wait to be revoked and take the self-staking amount back.\\n uint256 internal _waitingSecsToRevoke;\\n\\n /// @dev Mapping from active pool admin address => consensus address.\\n mapping(address => address) internal _activePoolAdminMapping;\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n */\\n uint256[49] private ______gap;\\n\\n modifier noEmptyValue() {\\n require(msg.value > 0, \\\"BaseStaking: query with empty value\\\");\\n _;\\n }\\n\\n modifier notPoolAdmin(PoolDetail storage _pool, address _delegator) {\\n require(_pool.admin != _delegator, \\\"BaseStaking: delegator must not be the pool admin\\\");\\n _;\\n }\\n\\n modifier onlyPoolAdmin(PoolDetail storage _pool, address _requester) {\\n require(_pool.admin == _requester, \\\"BaseStaking: requester must be the pool admin\\\");\\n _;\\n }\\n\\n modifier poolExists(address _poolAddr) {\\n require(_validatorContract.isValidatorCandidate(_poolAddr), \\\"BaseStaking: query for non-existent pool\\\");\\n _;\\n }\\n\\n /**\\n * @inheritdoc IBaseStaking\\n */\\n function isActivePoolAdmin(address _poolAdminAddr) public view override returns (bool) {\\n return _activePoolAdminMapping[_poolAdminAddr] != address(0);\\n }\\n\\n /**\\n * @inheritdoc IBaseStaking\\n */\\n function getPoolAddressOf(address _poolAdminAddr) external view override returns (address) {\\n return _activePoolAdminMapping[_poolAdminAddr];\\n }\\n\\n /**\\n * @inheritdoc IRewardPool\\n */\\n function getStakingTotal(address _poolAddr) public view override returns (uint256) {\\n return _stakingPool[_poolAddr].stakingTotal;\\n }\\n\\n /**\\n * @inheritdoc IRewardPool\\n */\\n function getManyStakingTotals(address[] calldata _poolList)\\n public\\n view\\n override\\n returns (uint256[] memory _stakingAmounts)\\n {\\n _stakingAmounts = new uint256[](_poolList.length);\\n for (uint _i = 0; _i < _poolList.length; _i++) {\\n _stakingAmounts[_i] = getStakingTotal(_poolList[_i]);\\n }\\n }\\n\\n /**\\n * @inheritdoc IRewardPool\\n */\\n function getStakingAmount(address _poolAddr, address _user) public view override returns (uint256) {\\n return _stakingPool[_poolAddr].delegatingAmount[_user];\\n }\\n\\n /**\\n * @inheritdoc IRewardPool\\n */\\n function getManyStakingAmounts(address[] calldata _poolAddrs, address[] calldata _userList)\\n external\\n view\\n override\\n returns (uint256[] memory _stakingAmounts)\\n {\\n require(_poolAddrs.length == _userList.length, \\\"BaseStaking: invalid input array\\\");\\n _stakingAmounts = new uint256[](_poolAddrs.length);\\n for (uint _i = 0; _i < _stakingAmounts.length; _i++) {\\n _stakingAmounts[_i] = _stakingPool[_poolAddrs[_i]].delegatingAmount[_userList[_i]];\\n }\\n }\\n\\n /**\\n * @inheritdoc IBaseStaking\\n */\\n function cooldownSecsToUndelegate() external view returns (uint256) {\\n return _cooldownSecsToUndelegate;\\n }\\n\\n /**\\n * @inheritdoc IBaseStaking\\n */\\n function waitingSecsToRevoke() external view returns (uint256) {\\n return _waitingSecsToRevoke;\\n }\\n\\n /**\\n * @inheritdoc IBaseStaking\\n */\\n function setCooldownSecsToUndelegate(uint256 _cooldownSecs) external override onlyAdmin {\\n _setCooldownSecsToUndelegate(_cooldownSecs);\\n }\\n\\n /**\\n * @inheritdoc IBaseStaking\\n */\\n function setWaitingSecsToRevoke(uint256 _secs) external override onlyAdmin {\\n _setWaitingSecsToRevoke(_secs);\\n }\\n\\n /**\\n * @dev Sets the minium number of seconds to undelegate.\\n *\\n * Emits the event `CooldownSecsToUndelegateUpdated`.\\n *\\n */\\n function _setCooldownSecsToUndelegate(uint256 _cooldownSecs) internal {\\n _cooldownSecsToUndelegate = _cooldownSecs;\\n emit CooldownSecsToUndelegateUpdated(_cooldownSecs);\\n }\\n\\n /**\\n * @dev Sets the number of seconds that a candidate must wait to be revoked.\\n *\\n * Emits the event `WaitingSecsToRevokeUpdated`.\\n *\\n */\\n function _setWaitingSecsToRevoke(uint256 _secs) internal {\\n _waitingSecsToRevoke = _secs;\\n emit WaitingSecsToRevokeUpdated(_secs);\\n }\\n\\n /**\\n * @dev Changes the delegate amount.\\n */\\n function _changeDelegatingAmount(\\n PoolDetail storage _pool,\\n address _delegator,\\n uint256 _newDelegatingAmount,\\n uint256 _newStakingTotal\\n ) internal {\\n _syncUserReward(_pool.addr, _delegator, _newDelegatingAmount);\\n _pool.stakingTotal = _newStakingTotal;\\n _pool.delegatingAmount[_delegator] = _newDelegatingAmount;\\n }\\n}\\n\",\"keccak256\":\"0xb982ec1be117a4d7abac36e6acffa13b830c6b7233acc46b8c71e63f4b9379de\",\"license\":\"MIT\"},\"contracts/ronin/staking/CandidateStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"../../libraries/AddressArrayUtils.sol\\\";\\nimport \\\"../../interfaces/staking/ICandidateStaking.sol\\\";\\nimport \\\"./BaseStaking.sol\\\";\\n\\nabstract contract CandidateStaking is BaseStaking, ICandidateStaking {\\n /// @dev The minimum threshold for being a validator candidate.\\n uint256 internal _minValidatorStakingAmount;\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n */\\n uint256[50] private ______gap;\\n\\n /**\\n * @inheritdoc ICandidateStaking\\n */\\n function minValidatorStakingAmount() public view override returns (uint256) {\\n return _minValidatorStakingAmount;\\n }\\n\\n /**\\n * @inheritdoc ICandidateStaking\\n */\\n function setMinValidatorStakingAmount(uint256 _threshold) external override onlyAdmin {\\n _setMinValidatorStakingAmount(_threshold);\\n }\\n\\n /**\\n * @inheritdoc ICandidateStaking\\n */\\n function applyValidatorCandidate(\\n address _candidateAdmin,\\n address _consensusAddr,\\n address payable _treasuryAddr,\\n address _bridgeOperatorAddr,\\n uint256 _commissionRate\\n ) external payable override nonReentrant {\\n require(!isActivePoolAdmin(msg.sender), \\\"CandidateStaking: pool admin is active\\\");\\n\\n uint256 _amount = msg.value;\\n address payable _poolAdmin = payable(msg.sender);\\n _applyValidatorCandidate(\\n _poolAdmin,\\n _candidateAdmin,\\n _consensusAddr,\\n _treasuryAddr,\\n _bridgeOperatorAddr,\\n _commissionRate,\\n _amount\\n );\\n\\n PoolDetail storage _pool = _stakingPool[_consensusAddr];\\n _pool.admin = _poolAdmin;\\n _pool.addr = _consensusAddr;\\n _activePoolAdminMapping[_poolAdmin] = _consensusAddr;\\n\\n _stake(_stakingPool[_consensusAddr], _poolAdmin, _amount);\\n emit PoolApproved(_consensusAddr, _poolAdmin);\\n }\\n\\n /**\\n * @inheritdoc ICandidateStaking\\n */\\n function requestUpdateCommissionRate(\\n address _consensusAddr,\\n uint256 _effectiveDaysOnwards,\\n uint256 _commissionRate\\n ) external override poolExists(_consensusAddr) onlyPoolAdmin(_stakingPool[_consensusAddr], msg.sender) {\\n _validatorContract.execRequestUpdateCommissionRate(_consensusAddr, _effectiveDaysOnwards, _commissionRate);\\n }\\n\\n /**\\n * @inheritdoc ICandidateStaking\\n */\\n function deprecatePools(address[] calldata _pools) external override onlyValidatorContract {\\n if (_pools.length == 0) {\\n return;\\n }\\n\\n uint256 _amount;\\n for (uint _i = 0; _i < _pools.length; _i++) {\\n PoolDetail storage _pool = _stakingPool[_pools[_i]];\\n // Deactivate the pool admin in the active mapping.\\n delete _activePoolAdminMapping[_pool.admin];\\n\\n // Deduct and transfer the self staking amount to the pool admin.\\n _amount = _pool.stakingAmount;\\n if (_amount > 0) {\\n _deductStakingAmount(_pool, _amount);\\n if (!_unsafeSendRON(payable(_pool.admin), _amount)) {\\n emit StakingAmountTransferFailed(_pool.addr, _pool.admin, _amount, address(this).balance);\\n }\\n }\\n }\\n\\n emit PoolsDeprecated(_pools);\\n }\\n\\n /**\\n * @inheritdoc ICandidateStaking\\n */\\n function stake(address _consensusAddr) external payable override noEmptyValue poolExists(_consensusAddr) {\\n _stake(_stakingPool[_consensusAddr], msg.sender, msg.value);\\n }\\n\\n /**\\n * @inheritdoc ICandidateStaking\\n */\\n function unstake(address _consensusAddr, uint256 _amount) external override nonReentrant poolExists(_consensusAddr) {\\n require(_amount > 0, \\\"CandidateStaking: invalid amount\\\");\\n address _delegator = msg.sender;\\n PoolDetail storage _pool = _stakingPool[_consensusAddr];\\n uint256 _remainAmount = _pool.stakingAmount - _amount;\\n require(_remainAmount >= _minValidatorStakingAmount, \\\"CandidateStaking: invalid staking amount left\\\");\\n\\n _unstake(_pool, _delegator, _amount);\\n require(_sendRON(payable(_delegator), _amount), \\\"CandidateStaking: could not transfer RON\\\");\\n }\\n\\n /**\\n * @inheritdoc ICandidateStaking\\n */\\n function requestRenounce(address _consensusAddr)\\n external\\n override\\n poolExists(_consensusAddr)\\n onlyPoolAdmin(_stakingPool[_consensusAddr], msg.sender)\\n {\\n _validatorContract.requestRevokeCandidate(_consensusAddr, _waitingSecsToRevoke);\\n }\\n\\n /**\\n * @dev See `ICandidateStaking-applyValidatorCandidate`\\n */\\n function _applyValidatorCandidate(\\n address payable _poolAdmin,\\n address _candidateAdmin,\\n address _consensusAddr,\\n address payable _treasuryAddr,\\n address _bridgeOperatorAddr,\\n uint256 _commissionRate,\\n uint256 _amount\\n ) internal {\\n require(_sendRON(_poolAdmin, 0), \\\"CandidateStaking: pool admin cannot receive RON\\\");\\n require(_sendRON(_treasuryAddr, 0), \\\"CandidateStaking: treasury cannot receive RON\\\");\\n require(_amount >= _minValidatorStakingAmount, \\\"CandidateStaking: insufficient amount\\\");\\n\\n require(\\n _poolAdmin == _candidateAdmin && _candidateAdmin == _treasuryAddr,\\n \\\"CandidateStaking: three interaction addresses must be of the same\\\"\\n );\\n\\n address[] memory _diffAddrs = new address[](3);\\n _diffAddrs[0] = _poolAdmin;\\n _diffAddrs[1] = _consensusAddr;\\n _diffAddrs[2] = _bridgeOperatorAddr;\\n require(\\n !AddressArrayUtils.hasDuplicate(_diffAddrs),\\n \\\"CandidateStaking: three operation addresses must be distinct\\\"\\n );\\n\\n _validatorContract.grantValidatorCandidate(\\n _candidateAdmin,\\n _consensusAddr,\\n _treasuryAddr,\\n _bridgeOperatorAddr,\\n _commissionRate\\n );\\n }\\n\\n /**\\n * @dev See `ICandidateStaking-stake`\\n */\\n function _stake(\\n PoolDetail storage _pool,\\n address _requester,\\n uint256 _amount\\n ) internal onlyPoolAdmin(_pool, _requester) {\\n _pool.stakingAmount += _amount;\\n _changeDelegatingAmount(_pool, _requester, _pool.stakingAmount, _pool.stakingTotal + _amount);\\n _pool.lastDelegatingTimestamp[_requester] = block.timestamp;\\n emit Staked(_pool.addr, _amount);\\n }\\n\\n /**\\n * @dev See `ICandidateStaking-unstake`\\n */\\n function _unstake(\\n PoolDetail storage _pool,\\n address _requester,\\n uint256 _amount\\n ) internal onlyPoolAdmin(_pool, _requester) {\\n require(_amount <= _pool.stakingAmount, \\\"CandidateStaking: insufficient staking amount\\\");\\n require(\\n _pool.lastDelegatingTimestamp[_requester] + _cooldownSecsToUndelegate <= block.timestamp,\\n \\\"CandidateStaking: unstake too early\\\"\\n );\\n\\n _pool.stakingAmount -= _amount;\\n _changeDelegatingAmount(_pool, _requester, _pool.stakingAmount, _pool.stakingTotal - _amount);\\n emit Unstaked(_pool.addr, _amount);\\n }\\n\\n /**\\n * @dev Deducts from staking amount of the validator `_consensusAddr` for `_amount`.\\n *\\n * Emits the event `Unstaked`.\\n *\\n * @return The actual deducted amount\\n */\\n function _deductStakingAmount(PoolDetail storage _pool, uint256 _amount) internal virtual returns (uint256);\\n\\n /**\\n * @dev Sets the minimum threshold for being a validator candidate.\\n *\\n * Emits the `MinValidatorStakingAmountUpdated` event.\\n *\\n */\\n function _setMinValidatorStakingAmount(uint256 _threshold) internal {\\n _minValidatorStakingAmount = _threshold;\\n emit MinValidatorStakingAmountUpdated(_threshold);\\n }\\n}\\n\",\"keccak256\":\"0xe80c374e9425772e3a50721371b108148b325bef59536e9ce7ca963f81d49f7e\",\"license\":\"MIT\"},\"contracts/ronin/staking/DelegatorStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"../../interfaces/staking/IDelegatorStaking.sol\\\";\\nimport \\\"./BaseStaking.sol\\\";\\n\\nabstract contract DelegatorStaking is BaseStaking, IDelegatorStaking {\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n */\\n uint256[50] private ______gap;\\n\\n /**\\n * @inheritdoc IDelegatorStaking\\n */\\n function delegate(address _consensusAddr) external payable noEmptyValue poolExists(_consensusAddr) {\\n require(!isActivePoolAdmin(msg.sender), \\\"DelegatorStaking: admin of an active pool cannot delegate\\\");\\n _delegate(_stakingPool[_consensusAddr], msg.sender, msg.value);\\n }\\n\\n /**\\n * @inheritdoc IDelegatorStaking\\n */\\n function undelegate(address _consensusAddr, uint256 _amount) external nonReentrant {\\n address payable _delegator = payable(msg.sender);\\n _undelegate(_stakingPool[_consensusAddr], _delegator, _amount);\\n require(_sendRON(_delegator, _amount), \\\"DelegatorStaking: could not transfer RON\\\");\\n }\\n\\n /**\\n * @inheritdoc IDelegatorStaking\\n */\\n function bulkUndelegate(address[] calldata _consensusAddrs, uint256[] calldata _amounts) external nonReentrant {\\n require(\\n _consensusAddrs.length > 0 && _consensusAddrs.length == _amounts.length,\\n \\\"DelegatorStaking: invalid array length\\\"\\n );\\n\\n address payable _delegator = payable(msg.sender);\\n uint256 _total;\\n\\n for (uint _i = 0; _i < _consensusAddrs.length; _i++) {\\n _total += _amounts[_i];\\n _undelegate(_stakingPool[_consensusAddrs[_i]], _delegator, _amounts[_i]);\\n }\\n\\n require(_sendRON(_delegator, _total), \\\"DelegatorStaking: could not transfer RON\\\");\\n }\\n\\n /**\\n * @inheritdoc IDelegatorStaking\\n */\\n function redelegate(\\n address _consensusAddrSrc,\\n address _consensusAddrDst,\\n uint256 _amount\\n ) external nonReentrant poolExists(_consensusAddrDst) {\\n address _delegator = msg.sender;\\n _undelegate(_stakingPool[_consensusAddrSrc], _delegator, _amount);\\n _delegate(_stakingPool[_consensusAddrDst], _delegator, _amount);\\n }\\n\\n /**\\n * @inheritdoc IDelegatorStaking\\n */\\n function claimRewards(address[] calldata _consensusAddrList)\\n external\\n override\\n nonReentrant\\n returns (uint256 _amount)\\n {\\n _amount = _claimRewards(msg.sender, _consensusAddrList);\\n _transferRON(payable(msg.sender), _amount);\\n }\\n\\n /**\\n * @inheritdoc IDelegatorStaking\\n */\\n function delegateRewards(address[] calldata _consensusAddrList, address _consensusAddrDst)\\n external\\n override\\n nonReentrant\\n poolExists(_consensusAddrDst)\\n returns (uint256 _amount)\\n {\\n return _delegateRewards(msg.sender, _consensusAddrList, _consensusAddrDst);\\n }\\n\\n /**\\n * @inheritdoc IDelegatorStaking\\n */\\n function getRewards(address _user, address[] calldata _poolAddrList)\\n external\\n view\\n returns (uint256[] memory _rewards)\\n {\\n address _consensusAddr;\\n uint256 _period = _validatorContract.currentPeriod();\\n _rewards = new uint256[](_poolAddrList.length);\\n\\n for (uint256 _i = 0; _i < _poolAddrList.length; _i++) {\\n _consensusAddr = _poolAddrList[_i];\\n _rewards[_i] = _getReward(_consensusAddr, _user, _period, getStakingAmount(_consensusAddr, _user));\\n }\\n }\\n\\n /**\\n * @dev Delegates from a validator address.\\n *\\n * Requirements:\\n * - The delegator is not the pool admin.\\n *\\n * Emits the `Delegated` event.\\n *\\n * Note: This function does not verify the `msg.value` with the amount.\\n *\\n */\\n function _delegate(\\n PoolDetail storage _pool,\\n address _delegator,\\n uint256 _amount\\n ) internal notPoolAdmin(_pool, _delegator) {\\n _changeDelegatingAmount(\\n _pool,\\n _delegator,\\n _pool.delegatingAmount[_delegator] + _amount,\\n _pool.stakingTotal + _amount\\n );\\n _pool.lastDelegatingTimestamp[_delegator] = block.timestamp;\\n emit Delegated(_delegator, _pool.addr, _amount);\\n }\\n\\n /**\\n * @dev Undelegates from a validator address.\\n *\\n * Requirements:\\n * - The delegator is not the pool admin.\\n * - The amount is larger than 0.\\n * - The delegating amount is larger than or equal to the undelegating amount.\\n *\\n * Emits the `Undelegated` event.\\n *\\n * Note: Consider transferring back the amount of RON after calling this function.\\n *\\n */\\n function _undelegate(\\n PoolDetail storage _pool,\\n address _delegator,\\n uint256 _amount\\n ) private notPoolAdmin(_pool, _delegator) {\\n require(_amount > 0, \\\"DelegatorStaking: invalid amount\\\");\\n require(_pool.delegatingAmount[_delegator] >= _amount, \\\"DelegatorStaking: insufficient amount to undelegate\\\");\\n require(\\n _pool.lastDelegatingTimestamp[_delegator] + _cooldownSecsToUndelegate < block.timestamp,\\n \\\"DelegatorStaking: undelegate too early\\\"\\n );\\n _changeDelegatingAmount(\\n _pool,\\n _delegator,\\n _pool.delegatingAmount[_delegator] - _amount,\\n _pool.stakingTotal - _amount\\n );\\n emit Undelegated(_delegator, _pool.addr, _amount);\\n }\\n\\n /**\\n * @dev Claims rewards from the pools `_poolAddrList`.\\n * Note: This function does not transfer reward to user.\\n */\\n function _claimRewards(address _user, address[] calldata _poolAddrList) internal returns (uint256 _amount) {\\n for (uint256 _i = 0; _i < _poolAddrList.length; _i++) {\\n _amount += _claimReward(_poolAddrList[_i], _user);\\n }\\n }\\n\\n /**\\n * @dev Claims the rewards and delegates them to the consensus address.\\n */\\n function _delegateRewards(\\n address _user,\\n address[] calldata _poolAddrList,\\n address _poolAddrDst\\n ) internal returns (uint256 _amount) {\\n _amount = _claimRewards(_user, _poolAddrList);\\n _delegate(_stakingPool[_poolAddrDst], _user, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xf398428c3d6123e20f0f05c6d0ccaaea6f3e6366a52a66620c82b77954ce66ad\",\"license\":\"MIT\"},\"contracts/ronin/staking/RewardCalculation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"../../interfaces/staking/IRewardPool.sol\\\";\\nimport \\\"../../libraries/Math.sol\\\";\\n\\n/**\\n * @title RewardCalculation contract\\n * @dev This contract mainly contains the methods to calculate reward for staking contract.\\n */\\nabstract contract RewardCalculation is IRewardPool {\\n /// @dev Mapping from pool address => period number => accumulated rewards per share (one unit staking)\\n mapping(address => mapping(uint256 => PeriodWrapper)) private _accumulatedRps;\\n /// @dev Mapping from the pool address => user address => the reward info of the user\\n mapping(address => mapping(address => UserRewardFields)) private _userReward;\\n /// @dev Mapping from the pool address => reward pool fields\\n mapping(address => PoolFields) private _stakingPool;\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n */\\n uint256[50] private ______gap;\\n\\n /**\\n * @inheritdoc IRewardPool\\n */\\n function getReward(address _poolAddr, address _user) external view returns (uint256) {\\n return _getReward(_poolAddr, _user, _currentPeriod(), getStakingAmount(_poolAddr, _user));\\n }\\n\\n /**\\n * @inheritdoc IRewardPool\\n */\\n function getStakingAmount(address _poolAddr, address _user) public view virtual returns (uint256);\\n\\n /**\\n * @inheritdoc IRewardPool\\n */\\n function getStakingTotal(address _poolAddr) public view virtual returns (uint256);\\n\\n /**\\n * @dev Returns the reward amount that user claimable.\\n */\\n function _getReward(\\n address _poolAddr,\\n address _user,\\n uint256 _latestPeriod,\\n uint256 _latestStakingAmount\\n ) internal view returns (uint256) {\\n UserRewardFields storage _reward = _userReward[_poolAddr][_user];\\n\\n if (_reward.lastPeriod == _latestPeriod) {\\n return _reward.debited;\\n }\\n\\n uint256 _aRps;\\n uint256 _lastPeriodReward;\\n PoolFields storage _pool = _stakingPool[_poolAddr];\\n PeriodWrapper storage _wrappedArps = _accumulatedRps[_poolAddr][_reward.lastPeriod];\\n\\n if (_wrappedArps.lastPeriod > 0) {\\n // Calculates the last period reward if the aRps at the period is set\\n _aRps = _accumulatedRps[_poolAddr][_reward.lastPeriod].inner;\\n _lastPeriodReward = _reward.minAmount * (_aRps - _reward.aRps);\\n } else {\\n // Fallbacks to the previous aRps in case the aRps is not set\\n _aRps = _reward.aRps;\\n }\\n\\n uint256 _newPeriodsReward = _latestStakingAmount * (_pool.aRps - _aRps);\\n return _reward.debited + (_lastPeriodReward + _newPeriodsReward) / 1e18;\\n }\\n\\n /**\\n * @dev Syncs the user reward.\\n *\\n * Emits the event `UserRewardUpdated` once the debit amount is updated.\\n * Emits the event `PoolSharesUpdated` once the pool share is updated.\\n *\\n * Note: The method should be called whenever the user's staking amount changes.\\n *\\n */\\n function _syncUserReward(\\n address _poolAddr,\\n address _user,\\n uint256 _newStakingAmount\\n ) internal {\\n uint256 _period = _currentPeriod();\\n PoolFields storage _pool = _stakingPool[_poolAddr];\\n uint256 _lastShares = _pool.shares.inner;\\n\\n // Updates the pool shares if it is outdated\\n if (_pool.shares.lastPeriod < _period) {\\n _pool.shares = PeriodWrapper(getStakingTotal(_poolAddr), _period);\\n }\\n\\n UserRewardFields storage _reward = _userReward[_poolAddr][_user];\\n uint256 _currentStakingAmount = getStakingAmount(_poolAddr, _user);\\n uint256 _debited = _getReward(_poolAddr, _user, _period, _currentStakingAmount);\\n\\n if (_reward.debited != _debited) {\\n _reward.debited = _debited;\\n emit UserRewardUpdated(_poolAddr, _user, _debited);\\n }\\n\\n _syncMinStakingAmount(_pool, _reward, _period, _newStakingAmount, _currentStakingAmount);\\n _reward.aRps = _pool.aRps;\\n _reward.lastPeriod = _period;\\n\\n if (_pool.shares.inner != _lastShares) {\\n emit PoolSharesUpdated(_period, _poolAddr, _pool.shares.inner);\\n }\\n }\\n\\n /**\\n * @dev Syncs the minimum staking amount of an user in the current period.\\n */\\n function _syncMinStakingAmount(\\n PoolFields storage _pool,\\n UserRewardFields storage _reward,\\n uint256 _latestPeriod,\\n uint256 _newStakingAmount,\\n uint256 _currentStakingAmount\\n ) internal {\\n if (_reward.lastPeriod < _latestPeriod) {\\n _reward.minAmount = _currentStakingAmount;\\n }\\n\\n uint256 _minAmount = Math.min(_reward.minAmount, _newStakingAmount);\\n uint256 _diffAmount = _reward.minAmount - _minAmount;\\n if (_diffAmount > 0) {\\n _reward.minAmount = _minAmount;\\n require(_pool.shares.inner >= _diffAmount, \\\"RewardCalculation: invalid pool shares\\\");\\n _pool.shares.inner -= _diffAmount;\\n }\\n }\\n\\n /**\\n * @dev Claims the settled reward for a specific user.\\n *\\n * Emits the `PendingRewardUpdated` event and the `SettledRewardUpdated` event.\\n *\\n * Note: This method should be called before transferring rewards for the user.\\n *\\n */\\n function _claimReward(address _poolAddr, address _user) internal returns (uint256 _amount) {\\n uint256 _latestPeriod = _currentPeriod();\\n _amount = _getReward(_poolAddr, _user, _latestPeriod, getStakingAmount(_poolAddr, _user));\\n emit RewardClaimed(_poolAddr, _user, _amount);\\n\\n UserRewardFields storage _reward = _userReward[_poolAddr][_user];\\n _reward.debited = 0;\\n _reward.lastPeriod = _latestPeriod;\\n _reward.aRps = _stakingPool[_poolAddr].aRps;\\n emit UserRewardUpdated(_poolAddr, _user, 0);\\n }\\n\\n /**\\n * @dev Records the amount of rewards `_rewards` for the pools `_poolAddrs`.\\n *\\n * Emits the event `PoolsUpdated` once the contract recorded the rewards successfully.\\n * Emits the event `PoolsUpdateFailed` once the input array lengths are not equal.\\n * Emits the event `PoolUpdateConflicted` when the pool is already updated in the period.\\n *\\n * Note: This method should be called once at the period ending.\\n *\\n */\\n function _recordRewards(\\n address[] memory _poolAddrs,\\n uint256[] calldata _rewards,\\n uint256 _period\\n ) internal {\\n if (_poolAddrs.length != _rewards.length) {\\n emit PoolsUpdateFailed(_period, _poolAddrs, _rewards);\\n return;\\n }\\n\\n uint256 _rps;\\n uint256 _count;\\n address _poolAddr;\\n uint256 _stakingTotal;\\n uint256[] memory _aRps = new uint256[](_poolAddrs.length);\\n uint256[] memory _shares = new uint256[](_poolAddrs.length);\\n address[] memory _conflicted = new address[](_poolAddrs.length);\\n\\n for (uint _i = 0; _i < _poolAddrs.length; _i++) {\\n _poolAddr = _poolAddrs[_i];\\n PoolFields storage _pool = _stakingPool[_poolAddr];\\n _stakingTotal = getStakingTotal(_poolAddr);\\n\\n if (_accumulatedRps[_poolAddr][_period].lastPeriod == _period) {\\n _conflicted[_count++] = _poolAddr;\\n continue;\\n }\\n\\n // Updates the pool shares if it is outdated\\n if (_pool.shares.lastPeriod < _period) {\\n _pool.shares = PeriodWrapper(_stakingTotal, _period);\\n }\\n\\n // The rps is 0 if no one stakes for the pool\\n _rps = _pool.shares.inner == 0 ? 0 : (_rewards[_i] * 1e18) / _pool.shares.inner;\\n _aRps[_i - _count] = _pool.aRps += _rps;\\n _accumulatedRps[_poolAddr][_period] = PeriodWrapper(_pool.aRps, _period);\\n if (_pool.shares.inner != _stakingTotal) {\\n _pool.shares.inner = _stakingTotal;\\n }\\n _shares[_i - _count] = _pool.shares.inner;\\n _poolAddrs[_i - _count] = _poolAddr;\\n }\\n\\n if (_count > 0) {\\n assembly {\\n mstore(_conflicted, _count)\\n mstore(_poolAddrs, sub(mload(_poolAddrs), _count))\\n }\\n emit PoolsUpdateConflicted(_period, _conflicted);\\n }\\n\\n if (_poolAddrs.length > 0) {\\n emit PoolsUpdated(_period, _poolAddrs, _aRps, _shares);\\n }\\n }\\n\\n /**\\n * @dev Returns the current period.\\n */\\n function _currentPeriod() internal view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0x43d7da0f22746bda6a2878f9ab10556a26910756b6ac26a58ec8221e3f09637f\",\"license\":\"MIT\"},\"contracts/ronin/staking/Staking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.9;\\n\\nimport \\\"@openzeppelin/contracts/proxy/utils/Initializable.sol\\\";\\nimport \\\"../../interfaces/staking/IStaking.sol\\\";\\nimport \\\"../../interfaces/validator/IRoninValidatorSet.sol\\\";\\nimport \\\"./CandidateStaking.sol\\\";\\nimport \\\"./DelegatorStaking.sol\\\";\\n\\ncontract Staking is IStaking, CandidateStaking, DelegatorStaking, Initializable {\\n constructor() {\\n _disableInitializers();\\n }\\n\\n receive() external payable onlyValidatorContract {}\\n\\n fallback() external payable onlyValidatorContract {}\\n\\n /**\\n * @dev Initializes the contract storage.\\n */\\n function initialize(\\n address __validatorContract,\\n uint256 __minValidatorStakingAmount,\\n uint256 __cooldownSecsToUndelegate,\\n uint256 __waitingSecsToRevoke\\n ) external initializer {\\n _setValidatorContract(__validatorContract);\\n _setMinValidatorStakingAmount(__minValidatorStakingAmount);\\n _setCooldownSecsToUndelegate(__cooldownSecsToUndelegate);\\n _setWaitingSecsToRevoke(__waitingSecsToRevoke);\\n }\\n\\n /**\\n * @inheritdoc IStaking\\n */\\n function getStakingPool(address _poolAddr)\\n external\\n view\\n poolExists(_poolAddr)\\n returns (\\n address _admin,\\n uint256 _stakingAmount,\\n uint256 _stakingTotal\\n )\\n {\\n PoolDetail storage _pool = _stakingPool[_poolAddr];\\n return (_pool.admin, _pool.stakingAmount, _pool.stakingTotal);\\n }\\n\\n /**\\n * @inheritdoc IStaking\\n */\\n function getManySelfStakings(address[] calldata _pools) external view returns (uint256[] memory _selfStakings) {\\n _selfStakings = new uint256[](_pools.length);\\n for (uint _i = 0; _i < _pools.length; _i++) {\\n _selfStakings[_i] = _stakingPool[_pools[_i]].stakingAmount;\\n }\\n }\\n\\n /**\\n * @inheritdoc IStaking\\n */\\n function recordRewards(\\n address[] calldata _consensusAddrs,\\n uint256[] calldata _rewards,\\n uint256 _period\\n ) external payable onlyValidatorContract {\\n _recordRewards(_consensusAddrs, _rewards, _period);\\n }\\n\\n /**\\n * @inheritdoc IStaking\\n */\\n function deductStakingAmount(address _consensusAddr, uint256 _amount)\\n external\\n onlyValidatorContract\\n returns (uint256 _actualDeductingAmount)\\n {\\n _actualDeductingAmount = _deductStakingAmount(_stakingPool[_consensusAddr], _amount);\\n address payable _recipientAddr = payable(validatorContract());\\n if (!_unsafeSendRON(_recipientAddr, _actualDeductingAmount)) {\\n emit StakingAmountDeductFailed(_consensusAddr, _recipientAddr, _actualDeductingAmount, address(this).balance);\\n }\\n }\\n\\n /**\\n * @inheritdoc RewardCalculation\\n */\\n function _currentPeriod() internal view virtual override returns (uint256) {\\n return _validatorContract.currentPeriod();\\n }\\n\\n /**\\n * @inheritdoc CandidateStaking\\n */\\n function _deductStakingAmount(PoolDetail storage _pool, uint256 _amount)\\n internal\\n override\\n returns (uint256 _actualDeductingAmount)\\n {\\n _actualDeductingAmount = Math.min(_pool.stakingAmount, _amount);\\n\\n _pool.stakingAmount -= _actualDeductingAmount;\\n _changeDelegatingAmount(_pool, _pool.admin, _pool.stakingAmount, _pool.stakingTotal - _actualDeductingAmount);\\n emit Unstaked(_pool.addr, _actualDeductingAmount);\\n }\\n}\\n\",\"keccak256\":\"0x904e300370b0fdc65a42a587097a77a284a270732abee90a5848a15ef716acfd\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b5060016000556200002162000027565b620000e9565b60d154610100900460ff1615620000945760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60d15460ff9081161015620000e75760d1805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b613d3d80620000f96000396000f3fe6080604052600436106101f25760003560e01c8063895ab7421161010d578063af245429116100a0578063cdf64a761161006f578063cdf64a761461060b578063e115877b1461062b578063e5376f5414610676578063e9ac5e0614610689578063f9f031df146106a95761023b565b8063af2454291461057d578063c2a672e014610592578063c5087003146105b2578063c905bb35146105eb5761023b565b80639488e4e9116100dc5780639488e4e9146104c6578063969ffc14146104e657806399439089146105065780639e614e0e146105385761023b565b8063895ab74214610438578063909791dd1461047157806391f8723f14610486578063924f081e146104a65761023b565b80634d99dd16116101855780636b091695116101545780636b091695146103b85780636bd8f804146103d857806376664b65146103f8578063888b9ae9146104185761023b565b80634d99dd16146103455780634ec81af1146103655780635c19a95c14610385578063679a6e43146103985761023b565b806326476204116101c157806326476204146102df5780633b8cb16b146102f25780633d8e846e1461030557806342ef3c34146103255761023b565b80630682e8fa1461024e578063095f647514610272578063097e4a9d1461029f5780631658c86e146102bf5761023b565b3661023b573361020a6036546001600160a01b031690565b6001600160a01b0316146102395760405162461bcd60e51b815260040161023090613476565b60405180910390fd5b005b3361020a6036546001600160a01b031690565b34801561025a57600080fd5b506038545b6040519081526020015b60405180910390f35b34801561027e57600080fd5b5061029261028d36600461351e565b6106c9565b60405161026991906135c4565b3480156102ab57600080fd5b5061025f6102ba3660046135ec565b61083a565b3480156102cb57600080fd5b506102396102da366004613642565b610907565b6102396102ed366004613642565b610a41565b610239610300366004613666565b610b12565b34801561031157600080fd5b506102926103203660046136d9565b610b93565b34801561033157600080fd5b5061029261034036600461372d565b610cd7565b34801561035157600080fd5b5061023961036036600461376e565b610dad565b34801561037157600080fd5b5061023961038036600461379a565b610e28565b610239610393366004613642565b610f58565b3480156103a457600080fd5b506102396103b33660046137d5565b6110b1565b3480156103c457600080fd5b5061025f6103d33660046137ee565b6110f5565b3480156103e457600080fd5b506102396103f3366004613827565b611117565b34801561040457600080fd5b5061025f6104133660046137ee565b61121c565b34801561042457600080fd5b506102396104333660046137d5565b61124b565b34801561044457600080fd5b5061025f610453366004613642565b6001600160a01b031660009081526037602052604090206003015490565b34801561047d57600080fd5b50606c5461025f565b34801561049257600080fd5b506102926104a136600461372d565b61128c565b3480156104b257600080fd5b506102396104c1366004613868565b611336565b3480156104d257600080fd5b506102396104e136600461351e565b611476565b3480156104f257600080fd5b506102396105013660046137d5565b6115ec565b34801561051257600080fd5b506036546001600160a01b03165b6040516001600160a01b039091168152602001610269565b34801561054457600080fd5b50610558610553366004613642565b61162d565b604080516001600160a01b039094168452602084019290925290820152606001610269565b34801561058957600080fd5b5060395461025f565b34801561059e57600080fd5b506102396105ad36600461376e565b6116f3565b3480156105be57600080fd5b506105206105cd366004613642565b6001600160a01b039081166000908152603a60205260409020541690565b3480156105f757600080fd5b5061025f61060636600461376e565b6118fb565b34801561061757600080fd5b50610239610626366004613642565b6119cd565b34801561063757600080fd5b50610666610646366004613642565b6001600160a01b039081166000908152603a602052604090205416151590565b6040519015158152602001610269565b61023961068436600461389d565b611a7a565b34801561069557600080fd5b506102396106a436600461372d565b611bd7565b3480156106b557600080fd5b5061025f6106c436600461372d565b611d66565b606083821461071a5760405162461bcd60e51b815260206004820181905260248201527f426173655374616b696e673a20696e76616c696420696e7075742061727261796044820152606401610230565b836001600160401b0381111561073257610732613901565b60405190808252806020026020018201604052801561075b578160200160208202803683370190505b50905060005b8151811015610831576037600087878481811061078057610780613917565b90506020020160208101906107959190613642565b6001600160a01b03166001600160a01b0316815260200190815260200160002060040160008585848181106107cc576107cc613917565b90506020020160208101906107e19190613642565b6001600160a01b03166001600160a01b031681526020019081526020016000205482828151811061081457610814613917565b60209081029190910101528061082981613943565b915050610761565b50949350505050565b600060026000540361085e5760405162461bcd60e51b81526004016102309061395c565b6002600055603654604051635061f96960e11b81526001600160a01b0380851660048301528492169063a0c3f2d290602401602060405180830381865afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190613993565b6108ed5760405162461bcd60e51b8152600401610230906139b5565b6108f933868686611db1565b600160005595945050505050565b603654604051635061f96960e11b81526001600160a01b0380841660048301528392169063a0c3f2d290602401602060405180830381865afa158015610951573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109759190613993565b6109915760405162461bcd60e51b8152600401610230906139b5565b6001600160a01b0380831660009081526037602052604090206001810154909133911681146109d25760405162461bcd60e51b8152600401610230906139fd565b603654603954604051636efa12bd60e01b81526001600160a01b0387811660048301526024820192909252911690636efa12bd90604401600060405180830381600087803b158015610a2357600080fd5b505af1158015610a37573d6000803e3d6000fd5b5050505050505050565b60003411610a615760405162461bcd60e51b815260040161023090613a4a565b603654604051635061f96960e11b81526001600160a01b0380841660048301528392169063a0c3f2d290602401602060405180830381865afa158015610aab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610acf9190613993565b610aeb5760405162461bcd60e51b8152600401610230906139b5565b6001600160a01b0382166000908152603760205260409020610b0e903334611dec565b5050565b33610b256036546001600160a01b031690565b6001600160a01b031614610b4b5760405162461bcd60e51b815260040161023090613476565b610b8c858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250879250869150859050611ebe565b5050505050565b6060600080603660009054906101000a90046001600160a01b03166001600160a01b031663060406186040518163ffffffff1660e01b8152600401602060405180830381865afa158015610beb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0f9190613a8d565b9050836001600160401b03811115610c2957610c29613901565b604051908082528060200260200182016040528015610c52578160200160208202803683370190505b50925060005b84811015610ccd57858582818110610c7257610c72613917565b9050602002016020810190610c879190613642565b9250610c9e838884610c99878c61121c565b6122f7565b848281518110610cb057610cb0613917565b602090810291909101015280610cc581613943565b915050610c58565b5050509392505050565b6060816001600160401b03811115610cf157610cf1613901565b604051908082528060200260200182016040528015610d1a578160200160208202803683370190505b50905060005b82811015610da65760376000858584818110610d3e57610d3e613917565b9050602002016020810190610d539190613642565b6001600160a01b03166001600160a01b0316815260200190815260200160002060020154828281518110610d8957610d89613917565b602090810291909101015280610d9e81613943565b915050610d20565b5092915050565b600260005403610dcf5760405162461bcd60e51b81526004016102309061395c565b600260009081556001600160a01b03831681526037602052604090203390610df8908284612419565b610e028183612631565b610e1e5760405162461bcd60e51b815260040161023090613aa6565b5050600160005550565b60d154610100900460ff1615808015610e48575060d154600160ff909116105b80610e625750303b158015610e62575060d15460ff166001145b610ec55760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610230565b60d1805460ff191660011790558015610ee85760d1805461ff0019166101001790555b610ef185612697565b610efa846126ec565b610f0383612721565b610f0c82612756565b8015610b8c5760d1805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b60003411610f785760405162461bcd60e51b815260040161023090613a4a565b603654604051635061f96960e11b81526001600160a01b0380841660048301528392169063a0c3f2d290602401602060405180830381865afa158015610fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe69190613993565b6110025760405162461bcd60e51b8152600401610230906139b5565b336000908152603a60205260409020546001600160a01b03161561108e5760405162461bcd60e51b815260206004820152603960248201527f44656c656761746f725374616b696e673a2061646d696e206f6620616e20616360448201527f7469766520706f6f6c2063616e6e6f742064656c6567617465000000000000006064820152608401610230565b6001600160a01b0382166000908152603760205260409020610b0e90333461278b565b6110b9612852565b6001600160a01b0316336001600160a01b0316146110e95760405162461bcd60e51b815260040161023090613aee565b6110f2816126ec565b50565b600061110e8383611104612880565b610c99878761121c565b90505b92915050565b6002600054036111395760405162461bcd60e51b81526004016102309061395c565b6002600055603654604051635061f96960e11b81526001600160a01b0380851660048301528492169063a0c3f2d290602401602060405180830381865afa158015611188573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ac9190613993565b6111c85760405162461bcd60e51b8152600401610230906139b5565b6001600160a01b038416600090815260376020526040902033906111ed908285612419565b6001600160a01b038416600090815260376020526040902061121090828561278b565b50506001600055505050565b6001600160a01b0391821660009081526037602090815260408083209390941682526004909201909152205490565b611253612852565b6001600160a01b0316336001600160a01b0316146112835760405162461bcd60e51b815260040161023090613aee565b6110f281612721565b6060816001600160401b038111156112a6576112a6613901565b6040519080825280602002602001820160405280156112cf578160200160208202803683370190505b50905060005b82811015610da6576113078484838181106112f2576112f2613917565b90506020020160208101906104539190613642565b82828151811061131957611319613917565b60209081029190910101528061132e81613943565b9150506112d5565b603654604051635061f96960e11b81526001600160a01b0380861660048301528592169063a0c3f2d290602401602060405180830381865afa158015611380573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a49190613993565b6113c05760405162461bcd60e51b8152600401610230906139b5565b6001600160a01b0380851660009081526037602052604090206001810154909133911681146114015760405162461bcd60e51b8152600401610230906139fd565b60365460405163e5125a1d60e01b81526001600160a01b03888116600483015260248201889052604482018790529091169063e5125a1d90606401600060405180830381600087803b15801561145657600080fd5b505af115801561146a573d6000803e3d6000fd5b50505050505050505050565b6002600054036114985760405162461bcd60e51b81526004016102309061395c565b600260005582158015906114ab57508281145b6115065760405162461bcd60e51b815260206004820152602660248201527f44656c656761746f725374616b696e673a20696e76616c6964206172726179206044820152650d8cadccee8d60d31b6064820152608401610230565b336000805b858110156115b85784848281811061152557611525613917565b90506020020135826115379190613b30565b91506115a66037600089898581811061155257611552613917565b90506020020160208101906115679190613642565b6001600160a01b03166001600160a01b031681526020019081526020016000208487878581811061159a5761159a613917565b90506020020135612419565b806115b081613943565b91505061150b565b506115c38282612631565b6115df5760405162461bcd60e51b815260040161023090613aa6565b5050600160005550505050565b6115f4612852565b6001600160a01b0316336001600160a01b0316146116245760405162461bcd60e51b815260040161023090613aee565b6110f281612756565b603654604051635061f96960e11b81526001600160a01b038084166004830152600092839283928692169063a0c3f2d290602401602060405180830381865afa15801561167e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a29190613993565b6116be5760405162461bcd60e51b8152600401610230906139b5565b505050506001600160a01b03908116600090815260376020526040902060018101546002820154600390920154921692909190565b6002600054036117155760405162461bcd60e51b81526004016102309061395c565b6002600055603654604051635061f96960e11b81526001600160a01b0380851660048301528492169063a0c3f2d290602401602060405180830381865afa158015611764573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117889190613993565b6117a45760405162461bcd60e51b8152600401610230906139b5565b600082116117f45760405162461bcd60e51b815260206004820181905260248201527f43616e6469646174655374616b696e673a20696e76616c696420616d6f756e746044820152606401610230565b6001600160a01b0383166000908152603760205260408120600281015433929061181f908690613b43565b9050606c548110156118895760405162461bcd60e51b815260206004820152602d60248201527f43616e6469646174655374616b696e673a20696e76616c6964207374616b696e60448201526c19c8185b5bdd5b9d081b19599d609a1b6064820152608401610230565b6118948284876128f2565b61189e8386612631565b6115df5760405162461bcd60e51b815260206004820152602860248201527f43616e6469646174655374616b696e673a20636f756c64206e6f74207472616e60448201526739b332b9102927a760c11b6064820152608401610230565b6000336119106036546001600160a01b031690565b6001600160a01b0316146119365760405162461bcd60e51b815260040161023090613476565b6001600160a01b03831660009081526037602052604090206119589083612a85565b9050600061196e6036546001600160a01b031690565b905061197a8183612b23565b610da657604080518381524760208201526001600160a01b0380841692908716917f63701cd972aa3c7f87898aab145c972e52185beab07d6e39380a998d334cf6c8910160405180910390a35092915050565b6119d5612852565b6001600160a01b0316336001600160a01b031614611a055760405162461bcd60e51b815260040161023090613aee565b6000816001600160a01b03163b11611a715760405162461bcd60e51b815260206004820152602960248201527f48617356616c696461746f72436f6e74726163743a2073657420746f206e6f6e6044820152680b58dbdb9d1c9858dd60ba1b6064820152608401610230565b6110f281612697565b600260005403611a9c5760405162461bcd60e51b81526004016102309061395c565b60026000908155338152603a60205260409020546001600160a01b031615611b155760405162461bcd60e51b815260206004820152602660248201527f43616e6469646174655374616b696e673a20706f6f6c2061646d696e2069732060448201526561637469766560d01b6064820152608401610230565b3433611b2681888888888888612b7f565b6001600160a01b0380871660008181526037602081815260408084206001810180549789166001600160a01b0319988916811790915581548816871782558552603a835290842080549096168517909555929091529052611b88818385611dec565b816001600160a01b0316876001600160a01b03167ffc1f1e73948cbc47c5b7f90e5601b7daccd9ad7173218486ccc74bdd051d05e860405160405180910390a350506001600055505050505050565b33611bea6036546001600160a01b031690565b6001600160a01b031614611c105760405162461bcd60e51b815260040161023090613476565b8015610b0e576000805b82811015611d2757600060376000868685818110611c3a57611c3a613917565b9050602002016020810190611c4f9190613642565b6001600160a01b0390811682526020808301939093526040918201600090812060018101549092168152603a909352912080546001600160a01b03191690556002810154935090508215611d1457611ca78184612a85565b506001810154611cc0906001600160a01b031684612b23565b611d145760018101548154604080518681524760208201526001600160a01b0393841693909216917f7dc5115a5aba081f5a174f56a3d02eea582824783322a4ac03f7bd388f444194910160405180910390a35b5080611d1f81613943565b915050611c1a565b507f4f257d3ba23679d338f1d94296086bba5724af341b7fa31aa0ff297bfcdc62d88383604051611d59929190613b56565b60405180910390a1505050565b6000600260005403611d8a5760405162461bcd60e51b81526004016102309061395c565b6002600055611d9a338484612f2c565b9050611da63382612f8e565b600160005592915050565b6000611dbe858585612f2c565b6001600160a01b0383166000908152603760205260409020909150611de490868361278b565b949350505050565b6001830154839083906001600160a01b03808316911614611e1f5760405162461bcd60e51b8152600401610230906139fd565b82856002016000828254611e339190613b30565b92505081905550611e5985858760020154868960030154611e549190613b30565b613015565b6001600160a01b03808516600090815260058701602052604090819020429055865490519116907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d90611eaf9086815260200190565b60405180910390a25050505050565b83518214611f0757807fae52c603227f64e4c6101dde593aa9790a16b3ac77546bd746d758511e9560a5858585604051611efa93929190613bdd565b60405180910390a26122f1565b600080600080600088516001600160401b03811115611f2857611f28613901565b604051908082528060200260200182016040528015611f51578160200160208202803683370190505b509050600089516001600160401b03811115611f6f57611f6f613901565b604051908082528060200260200182016040528015611f98578160200160208202803683370190505b50905060008a516001600160401b03811115611fb657611fb6613901565b604051908082528060200260200182016040528015611fdf578160200160208202803683370190505b50905060005b8b5181101561225c578b818151811061200057612000613917565b6020908102919091018101516001600160a01b038116600090815260038084526040808320603790955290912001549097506001600160a01b03881660009081526001602081815260408084208f855290915290912001549096508a90036120a65786838961206e81613943565b9a508151811061208057612080613917565b60200260200101906001600160a01b031690816001600160a01b0316815250505061224a565b60028101548a11156120d457604080518082019091528681526020018a905260018101869055600281018a90555b60018101541561211e5760018101548c8c848181106120f5576120f5613917565b90506020020135670de0b6b3a764000061210f9190613c27565b6121199190613c3e565b612121565b60005b9850888160000160008282546121379190613b30565b91829055509050856121498a85613b43565b8151811061215957612159613917565b6020026020010181815250506040518060400160405280826000015481526020018b81525060016000896001600160a01b03166001600160a01b0316815260200190815260200160002060008c81526020019081526020016000206000820151816000015560208201518160010155905050858160010160000154146121e157600181018690555b6001810154846121f18a85613b43565b8151811061220157612201613917565b6020908102919091010152868d6122188a85613b43565b8151811061222857612228613917565b60200260200101906001600160a01b031690816001600160a01b031681525050505b8061225481613943565b915050611fe5565b5085156122a557858152858b51038b52877fee74f10cc50bf4b7e57fd36be7d46288795f3a9151dae97505b718b392ba14a38260405161229c9190613c60565b60405180910390a25b8a51156122e957877f0e54e0485f70f0f63bc25889ddbf01ce1269ad6f07fdb2df573a0fbdb4d66f888c85856040516122e093929190613c73565b60405180910390a25b505050505050505b50505050565b6001600160a01b0380851660009081526002602090815260408083209387168352929052908120600381015484900361233257549050611de4565b6001600160a01b0386166000908152600360208181526040808420600180845282862094870154865293909252832091820154839290156123bd576001600160a01b038a16600090815260016020818152604080842060038a0154855290915290912054908601549094506123a79085613b43565b85600201546123b69190613c27565b92506123c5565b846001015493505b81546000906123d5908690613b43565b6123df9089613c27565b9050670de0b6b3a76400006123f48286613b30565b6123fe9190613c3e565b865461240a9190613b30565b9b9a5050505050505050505050565b6001830154839083906001600160a01b0380831691160361244c5760405162461bcd60e51b815260040161023090613cb6565b6000831161249c5760405162461bcd60e51b815260206004820181905260248201527f44656c656761746f725374616b696e673a20696e76616c696420616d6f756e746044820152606401610230565b6001600160a01b03841660009081526004860160205260409020548311156125225760405162461bcd60e51b815260206004820152603360248201527f44656c656761746f725374616b696e673a20696e73756666696369656e7420616044820152726d6f756e7420746f20756e64656c656761746560681b6064820152608401610230565b6038546001600160a01b0385166000908152600587016020526040902054429161254b91613b30565b106125a75760405162461bcd60e51b815260206004820152602660248201527f44656c656761746f725374616b696e673a20756e64656c656761746520746f6f604482015265206561726c7960d01b6064820152608401610230565b6001600160a01b03841660009081526004860160205260409020546125e590869086906125d5908790613b43565b868960030154611e549190613b43565b84546040518481526001600160a01b03918216918616907f4d10bd049775c77bd7f255195afba5088028ecb3c7c277d393ccff7934f2f92c906020015b60405180910390a35050505050565b60008147101561268d5760405162461bcd60e51b815260206004820152602160248201527f524f4e5472616e736665723a20696e73756666696369656e742062616c616e636044820152606560f81b6064820152608401610230565b61110e8383612b23565b603680546001600160a01b0319166001600160a01b0383169081179091556040519081527fef40dc07567635f84f5edbd2f8dbc16b40d9d282dd8e7e6f4ff58236b6836169906020015b60405180910390a150565b606c8190556040518181527f372bbdb8d72373b0012f84ee5a11671e5fb72b8bea902ebca93a19cb45d32be2906020016126e1565b60388190556040518181527f4956b65267b8f1e642284bcb5037116c69a9c78d9ca576beeae0974737a4872a906020016126e1565b60398190556040518181527f02be0b73b597f2c0f138aebee162b3b0e25d5b5a26854c15dcf79176e9a1c678906020016126e1565b6001830154839083906001600160a01b038083169116036127be5760405162461bcd60e51b815260040161023090613cb6565b6001600160a01b03841660009081526004860160205260409020546127fc90869086906127ec908790613b30565b868960030154611e549190613b30565b6001600160a01b03808516600081815260058801602052604090819020429055875490519216917fe5541a6b6103d4fa7e021ed54fad39c66f27a76bd13d374cf6240ae6bd0bb72b906126229087815260200190565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103546001600160a01b031690565b6036546040805162c080c360e31b815290516000926001600160a01b03169163060406189160048083019260209291908290030181865afa1580156128c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128ed9190613a8d565b905090565b6001830154839083906001600160a01b038083169116146129255760405162461bcd60e51b8152600401610230906139fd565b846002015483111561298f5760405162461bcd60e51b815260206004820152602d60248201527f43616e6469646174655374616b696e673a20696e73756666696369656e74207360448201526c1d185ada5b99c8185b5bdd5b9d609a1b6064820152608401610230565b6038546001600160a01b038516600090815260058701602052604090205442916129b891613b30565b1115612a125760405162461bcd60e51b815260206004820152602360248201527f43616e6469646174655374616b696e673a20756e7374616b6520746f6f206561604482015262726c7960e81b6064820152608401610230565b82856002016000828254612a269190613b43565b92505081905550612a4785858760020154868960030154611e549190613b43565b84546040518481526001600160a01b03909116907f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f7590602001611eaf565b6000612a95836002015483613050565b905080836002016000828254612aab9190613b43565b9091555050600183015460028401546003850154612adc9286926001600160a01b0390911691611e54908690613b43565b82546040518281526001600160a01b03909116907f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f759060200160405180910390a292915050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612b70576040519150601f19603f3d011682016040523d82523d6000602084013e612b75565b606091505b5090949350505050565b612b8a876000612631565b612bee5760405162461bcd60e51b815260206004820152602f60248201527f43616e6469646174655374616b696e673a20706f6f6c2061646d696e2063616e60448201526e3737ba103932b1b2b4bb32902927a760891b6064820152608401610230565b612bf9846000612631565b612c5b5760405162461bcd60e51b815260206004820152602d60248201527f43616e6469646174655374616b696e673a2074726561737572792063616e6e6f60448201526c3a103932b1b2b4bb32902927a760991b6064820152608401610230565b606c54811015612cbb5760405162461bcd60e51b815260206004820152602560248201527f43616e6469646174655374616b696e673a20696e73756666696369656e7420616044820152641b5bdd5b9d60da1b6064820152608401610230565b856001600160a01b0316876001600160a01b0316148015612ced5750836001600160a01b0316866001600160a01b0316145b612d695760405162461bcd60e51b815260206004820152604160248201527f43616e6469646174655374616b696e673a20746872656520696e74657261637460448201527f696f6e20616464726573736573206d757374206265206f66207468652073616d6064820152606560f81b608482015260a401610230565b60408051600380825260808201909252600091602082016060803683370190505090508781600081518110612da057612da0613917565b60200260200101906001600160a01b031690816001600160a01b0316815250508581600181518110612dd457612dd4613917565b60200260200101906001600160a01b031690816001600160a01b0316815250508381600281518110612e0857612e08613917565b60200260200101906001600160a01b031690816001600160a01b031681525050612e3181613066565b15612ea45760405162461bcd60e51b815260206004820152603c60248201527f43616e6469646174655374616b696e673a207468726565206f7065726174696f60448201527f6e20616464726573736573206d7573742062652064697374696e6374000000006064820152608401610230565b603654604051630733ec9760e41b81526001600160a01b038981166004830152888116602483015287811660448301528681166064830152608482018690529091169063733ec9709060a401600060405180830381600087803b158015612f0a57600080fd5b505af1158015612f1e573d6000803e3d6000fd5b505050505050505050505050565b6000805b82811015612f8657612f68848483818110612f4d57612f4d613917565b9050602002016020810190612f629190613642565b8661312d565b612f729083613b30565b915080612f7e81613943565b915050612f30565b509392505050565b612f988282612631565b610b0e5760405162461bcd60e51b815260206004820152604260248201527f524f4e5472616e736665723a20756e61626c6520746f207472616e736665722060448201527f76616c75652c20726563697069656e74206d6179206861766520726576657274606482015261195960f21b608482015260a401610230565b835461302b906001600160a01b03168484613215565b60038401556001600160a01b0390911660009081526004909201602052604090912055565b600081831061305f578161110e565b5090919050565b6000815160000361307957506000919050565b60005b6001835161308a9190613b43565b81101561312457600061309e826001613b30565b90505b8351811015613111578381815181106130bc576130bc613917565b60200260200101516001600160a01b03168483815181106130df576130df613917565b60200260200101516001600160a01b0316036130ff575060019392505050565b8061310981613943565b9150506130a1565b508061311c81613943565b91505061307c565b50600092915050565b600080613138612880565b905061314a848483610c99888861121c565b9150826001600160a01b0316846001600160a01b03167f0aa4d283470c904c551d18bb894d37e17674920f3261a7f854be501e25f421b78460405161319191815260200190565b60405180910390a36001600160a01b0384811660008181526002602090815260408083209488168084529482528083208381556003808201889055858552835281842054600182015590519283529392917faa7c29611027fd4be148712bb54960253b7a7d5998c17769bfc424c2f5f185ad910160405180910390a3505092915050565b600061321f612880565b6001600160a01b038516600090815260036020526040902060018101546002820154929350909183111561329357604051806040016040528061327a886001600160a01b031660009081526037602052604090206003015490565b8152602090810185905281516001850155015160028301555b6001600160a01b0380871660009081526002602090815260408083209389168352929052908120906132c5888861121c565b905060006132d5898988856122f7565b83549091508114613327578083556040518181526001600160a01b0389811691908b16907faa7c29611027fd4be148712bb54960253b7a7d5998c17769bfc424c2f5f185ad9060200160405180910390a35b6133348584888a866133a6565b845460018085019190915560038401879055850154841461339b57886001600160a01b0316867f81faf50e2aaf52eaba2ab841071efb9f6f0850a3e7d008b1336e6001d3d4963c876001016000015460405161339291815260200190565b60405180910390a35b505050505050505050565b82846003015410156133ba57600284018190555b60006133ca856002015484613050565b905060008186600201546133de9190613b43565b9050801561346d576002860182905560018701548111156134505760405162461bcd60e51b815260206004820152602660248201527f52657761726443616c63756c6174696f6e3a20696e76616c696420706f6f6c2060448201526573686172657360d01b6064820152608401610230565b808760010160000160008282546134679190613b43565b90915550505b50505050505050565b6020808252603e908201527f48617356616c696461746f72436f6e74726163743a206d6574686f642063616c60408201527f6c6572206d7573742062652076616c696461746f7220636f6e74726163740000606082015260800190565b60008083601f8401126134e557600080fd5b5081356001600160401b038111156134fc57600080fd5b6020830191508360208260051b850101111561351757600080fd5b9250929050565b6000806000806040858703121561353457600080fd5b84356001600160401b038082111561354b57600080fd5b613557888389016134d3565b9096509450602087013591508082111561357057600080fd5b5061357d878288016134d3565b95989497509550505050565b600081518084526020808501945080840160005b838110156135b95781518752958201959082019060010161359d565b509495945050505050565b60208152600061110e6020830184613589565b6001600160a01b03811681146110f257600080fd5b60008060006040848603121561360157600080fd5b83356001600160401b0381111561361757600080fd5b613623868287016134d3565b9094509250506020840135613637816135d7565b809150509250925092565b60006020828403121561365457600080fd5b813561365f816135d7565b9392505050565b60008060008060006060868803121561367e57600080fd5b85356001600160401b038082111561369557600080fd5b6136a189838a016134d3565b909750955060208801359150808211156136ba57600080fd5b506136c7888289016134d3565b96999598509660400135949350505050565b6000806000604084860312156136ee57600080fd5b83356136f9816135d7565b925060208401356001600160401b0381111561371457600080fd5b613720868287016134d3565b9497909650939450505050565b6000806020838503121561374057600080fd5b82356001600160401b0381111561375657600080fd5b613762858286016134d3565b90969095509350505050565b6000806040838503121561378157600080fd5b823561378c816135d7565b946020939093013593505050565b600080600080608085870312156137b057600080fd5b84356137bb816135d7565b966020860135965060408601359560600135945092505050565b6000602082840312156137e757600080fd5b5035919050565b6000806040838503121561380157600080fd5b823561380c816135d7565b9150602083013561381c816135d7565b809150509250929050565b60008060006060848603121561383c57600080fd5b8335613847816135d7565b92506020840135613857816135d7565b929592945050506040919091013590565b60008060006060848603121561387d57600080fd5b8335613888816135d7565b95602085013595506040909401359392505050565b600080600080600060a086880312156138b557600080fd5b85356138c0816135d7565b945060208601356138d0816135d7565b935060408601356138e0816135d7565b925060608601356138f0816135d7565b949793965091946080013592915050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016139555761395561392d565b5060010190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000602082840312156139a557600080fd5b8151801515811461365f57600080fd5b60208082526028908201527f426173655374616b696e673a20717565727920666f72206e6f6e2d6578697374604082015267195b9d081c1bdbdb60c21b606082015260800190565b6020808252602d908201527f426173655374616b696e673a20726571756573746572206d757374206265207460408201526c3432903837b7b61030b236b4b760991b606082015260800190565b60208082526023908201527f426173655374616b696e673a207175657279207769746820656d7074792076616040820152626c756560e81b606082015260800190565b600060208284031215613a9f57600080fd5b5051919050565b60208082526028908201527f44656c656761746f725374616b696e673a20636f756c64206e6f74207472616e60408201526739b332b9102927a760c11b606082015260800190565b60208082526022908201527f48617350726f787941646d696e3a20756e617574686f72697a65642073656e6460408201526132b960f11b606082015260800190565b808201808211156111115761111161392d565b818103818111156111115761111161392d565b60208082528181018390526000908460408401835b86811015613b99578235613b7e816135d7565b6001600160a01b031682529183019190830190600101613b6b565b509695505050505050565b600081518084526020808501945080840160005b838110156135b95781516001600160a01b031687529582019590820190600101613bb8565b604081526000613bf06040830186613ba4565b82810360208401528381526001600160fb1b03841115613c0f57600080fd5b8360051b808660208401370160200195945050505050565b80820281158282048414176111115761111161392d565b600082613c5b57634e487b7160e01b600052601260045260246000fd5b500490565b60208152600061110e6020830184613ba4565b606081526000613c866060830186613ba4565b8281036020840152613c988186613589565b90508281036040840152613cac8185613589565b9695505050505050565b60208082526031908201527f426173655374616b696e673a2064656c656761746f72206d757374206e6f74206040820152703132903a3432903837b7b61030b236b4b760791b60608201526080019056fea2646970667358221220e83be7b4fb217626c75492f6661dab51328551fb354334680cab37b9f5d5b0cf64736f6c63430008110033", + "deployedBytecode": "0x6080604052600436106101f25760003560e01c8063895ab7421161010d578063af245429116100a0578063cdf64a761161006f578063cdf64a761461060b578063e115877b1461062b578063e5376f5414610676578063e9ac5e0614610689578063f9f031df146106a95761023b565b8063af2454291461057d578063c2a672e014610592578063c5087003146105b2578063c905bb35146105eb5761023b565b80639488e4e9116100dc5780639488e4e9146104c6578063969ffc14146104e657806399439089146105065780639e614e0e146105385761023b565b8063895ab74214610438578063909791dd1461047157806391f8723f14610486578063924f081e146104a65761023b565b80634d99dd16116101855780636b091695116101545780636b091695146103b85780636bd8f804146103d857806376664b65146103f8578063888b9ae9146104185761023b565b80634d99dd16146103455780634ec81af1146103655780635c19a95c14610385578063679a6e43146103985761023b565b806326476204116101c157806326476204146102df5780633b8cb16b146102f25780633d8e846e1461030557806342ef3c34146103255761023b565b80630682e8fa1461024e578063095f647514610272578063097e4a9d1461029f5780631658c86e146102bf5761023b565b3661023b573361020a6036546001600160a01b031690565b6001600160a01b0316146102395760405162461bcd60e51b815260040161023090613476565b60405180910390fd5b005b3361020a6036546001600160a01b031690565b34801561025a57600080fd5b506038545b6040519081526020015b60405180910390f35b34801561027e57600080fd5b5061029261028d36600461351e565b6106c9565b60405161026991906135c4565b3480156102ab57600080fd5b5061025f6102ba3660046135ec565b61083a565b3480156102cb57600080fd5b506102396102da366004613642565b610907565b6102396102ed366004613642565b610a41565b610239610300366004613666565b610b12565b34801561031157600080fd5b506102926103203660046136d9565b610b93565b34801561033157600080fd5b5061029261034036600461372d565b610cd7565b34801561035157600080fd5b5061023961036036600461376e565b610dad565b34801561037157600080fd5b5061023961038036600461379a565b610e28565b610239610393366004613642565b610f58565b3480156103a457600080fd5b506102396103b33660046137d5565b6110b1565b3480156103c457600080fd5b5061025f6103d33660046137ee565b6110f5565b3480156103e457600080fd5b506102396103f3366004613827565b611117565b34801561040457600080fd5b5061025f6104133660046137ee565b61121c565b34801561042457600080fd5b506102396104333660046137d5565b61124b565b34801561044457600080fd5b5061025f610453366004613642565b6001600160a01b031660009081526037602052604090206003015490565b34801561047d57600080fd5b50606c5461025f565b34801561049257600080fd5b506102926104a136600461372d565b61128c565b3480156104b257600080fd5b506102396104c1366004613868565b611336565b3480156104d257600080fd5b506102396104e136600461351e565b611476565b3480156104f257600080fd5b506102396105013660046137d5565b6115ec565b34801561051257600080fd5b506036546001600160a01b03165b6040516001600160a01b039091168152602001610269565b34801561054457600080fd5b50610558610553366004613642565b61162d565b604080516001600160a01b039094168452602084019290925290820152606001610269565b34801561058957600080fd5b5060395461025f565b34801561059e57600080fd5b506102396105ad36600461376e565b6116f3565b3480156105be57600080fd5b506105206105cd366004613642565b6001600160a01b039081166000908152603a60205260409020541690565b3480156105f757600080fd5b5061025f61060636600461376e565b6118fb565b34801561061757600080fd5b50610239610626366004613642565b6119cd565b34801561063757600080fd5b50610666610646366004613642565b6001600160a01b039081166000908152603a602052604090205416151590565b6040519015158152602001610269565b61023961068436600461389d565b611a7a565b34801561069557600080fd5b506102396106a436600461372d565b611bd7565b3480156106b557600080fd5b5061025f6106c436600461372d565b611d66565b606083821461071a5760405162461bcd60e51b815260206004820181905260248201527f426173655374616b696e673a20696e76616c696420696e7075742061727261796044820152606401610230565b836001600160401b0381111561073257610732613901565b60405190808252806020026020018201604052801561075b578160200160208202803683370190505b50905060005b8151811015610831576037600087878481811061078057610780613917565b90506020020160208101906107959190613642565b6001600160a01b03166001600160a01b0316815260200190815260200160002060040160008585848181106107cc576107cc613917565b90506020020160208101906107e19190613642565b6001600160a01b03166001600160a01b031681526020019081526020016000205482828151811061081457610814613917565b60209081029190910101528061082981613943565b915050610761565b50949350505050565b600060026000540361085e5760405162461bcd60e51b81526004016102309061395c565b6002600055603654604051635061f96960e11b81526001600160a01b0380851660048301528492169063a0c3f2d290602401602060405180830381865afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190613993565b6108ed5760405162461bcd60e51b8152600401610230906139b5565b6108f933868686611db1565b600160005595945050505050565b603654604051635061f96960e11b81526001600160a01b0380841660048301528392169063a0c3f2d290602401602060405180830381865afa158015610951573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109759190613993565b6109915760405162461bcd60e51b8152600401610230906139b5565b6001600160a01b0380831660009081526037602052604090206001810154909133911681146109d25760405162461bcd60e51b8152600401610230906139fd565b603654603954604051636efa12bd60e01b81526001600160a01b0387811660048301526024820192909252911690636efa12bd90604401600060405180830381600087803b158015610a2357600080fd5b505af1158015610a37573d6000803e3d6000fd5b5050505050505050565b60003411610a615760405162461bcd60e51b815260040161023090613a4a565b603654604051635061f96960e11b81526001600160a01b0380841660048301528392169063a0c3f2d290602401602060405180830381865afa158015610aab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610acf9190613993565b610aeb5760405162461bcd60e51b8152600401610230906139b5565b6001600160a01b0382166000908152603760205260409020610b0e903334611dec565b5050565b33610b256036546001600160a01b031690565b6001600160a01b031614610b4b5760405162461bcd60e51b815260040161023090613476565b610b8c858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250879250869150859050611ebe565b5050505050565b6060600080603660009054906101000a90046001600160a01b03166001600160a01b031663060406186040518163ffffffff1660e01b8152600401602060405180830381865afa158015610beb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0f9190613a8d565b9050836001600160401b03811115610c2957610c29613901565b604051908082528060200260200182016040528015610c52578160200160208202803683370190505b50925060005b84811015610ccd57858582818110610c7257610c72613917565b9050602002016020810190610c879190613642565b9250610c9e838884610c99878c61121c565b6122f7565b848281518110610cb057610cb0613917565b602090810291909101015280610cc581613943565b915050610c58565b5050509392505050565b6060816001600160401b03811115610cf157610cf1613901565b604051908082528060200260200182016040528015610d1a578160200160208202803683370190505b50905060005b82811015610da65760376000858584818110610d3e57610d3e613917565b9050602002016020810190610d539190613642565b6001600160a01b03166001600160a01b0316815260200190815260200160002060020154828281518110610d8957610d89613917565b602090810291909101015280610d9e81613943565b915050610d20565b5092915050565b600260005403610dcf5760405162461bcd60e51b81526004016102309061395c565b600260009081556001600160a01b03831681526037602052604090203390610df8908284612419565b610e028183612631565b610e1e5760405162461bcd60e51b815260040161023090613aa6565b5050600160005550565b60d154610100900460ff1615808015610e48575060d154600160ff909116105b80610e625750303b158015610e62575060d15460ff166001145b610ec55760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610230565b60d1805460ff191660011790558015610ee85760d1805461ff0019166101001790555b610ef185612697565b610efa846126ec565b610f0383612721565b610f0c82612756565b8015610b8c5760d1805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b60003411610f785760405162461bcd60e51b815260040161023090613a4a565b603654604051635061f96960e11b81526001600160a01b0380841660048301528392169063a0c3f2d290602401602060405180830381865afa158015610fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe69190613993565b6110025760405162461bcd60e51b8152600401610230906139b5565b336000908152603a60205260409020546001600160a01b03161561108e5760405162461bcd60e51b815260206004820152603960248201527f44656c656761746f725374616b696e673a2061646d696e206f6620616e20616360448201527f7469766520706f6f6c2063616e6e6f742064656c6567617465000000000000006064820152608401610230565b6001600160a01b0382166000908152603760205260409020610b0e90333461278b565b6110b9612852565b6001600160a01b0316336001600160a01b0316146110e95760405162461bcd60e51b815260040161023090613aee565b6110f2816126ec565b50565b600061110e8383611104612880565b610c99878761121c565b90505b92915050565b6002600054036111395760405162461bcd60e51b81526004016102309061395c565b6002600055603654604051635061f96960e11b81526001600160a01b0380851660048301528492169063a0c3f2d290602401602060405180830381865afa158015611188573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ac9190613993565b6111c85760405162461bcd60e51b8152600401610230906139b5565b6001600160a01b038416600090815260376020526040902033906111ed908285612419565b6001600160a01b038416600090815260376020526040902061121090828561278b565b50506001600055505050565b6001600160a01b0391821660009081526037602090815260408083209390941682526004909201909152205490565b611253612852565b6001600160a01b0316336001600160a01b0316146112835760405162461bcd60e51b815260040161023090613aee565b6110f281612721565b6060816001600160401b038111156112a6576112a6613901565b6040519080825280602002602001820160405280156112cf578160200160208202803683370190505b50905060005b82811015610da6576113078484838181106112f2576112f2613917565b90506020020160208101906104539190613642565b82828151811061131957611319613917565b60209081029190910101528061132e81613943565b9150506112d5565b603654604051635061f96960e11b81526001600160a01b0380861660048301528592169063a0c3f2d290602401602060405180830381865afa158015611380573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a49190613993565b6113c05760405162461bcd60e51b8152600401610230906139b5565b6001600160a01b0380851660009081526037602052604090206001810154909133911681146114015760405162461bcd60e51b8152600401610230906139fd565b60365460405163e5125a1d60e01b81526001600160a01b03888116600483015260248201889052604482018790529091169063e5125a1d90606401600060405180830381600087803b15801561145657600080fd5b505af115801561146a573d6000803e3d6000fd5b50505050505050505050565b6002600054036114985760405162461bcd60e51b81526004016102309061395c565b600260005582158015906114ab57508281145b6115065760405162461bcd60e51b815260206004820152602660248201527f44656c656761746f725374616b696e673a20696e76616c6964206172726179206044820152650d8cadccee8d60d31b6064820152608401610230565b336000805b858110156115b85784848281811061152557611525613917565b90506020020135826115379190613b30565b91506115a66037600089898581811061155257611552613917565b90506020020160208101906115679190613642565b6001600160a01b03166001600160a01b031681526020019081526020016000208487878581811061159a5761159a613917565b90506020020135612419565b806115b081613943565b91505061150b565b506115c38282612631565b6115df5760405162461bcd60e51b815260040161023090613aa6565b5050600160005550505050565b6115f4612852565b6001600160a01b0316336001600160a01b0316146116245760405162461bcd60e51b815260040161023090613aee565b6110f281612756565b603654604051635061f96960e11b81526001600160a01b038084166004830152600092839283928692169063a0c3f2d290602401602060405180830381865afa15801561167e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a29190613993565b6116be5760405162461bcd60e51b8152600401610230906139b5565b505050506001600160a01b03908116600090815260376020526040902060018101546002820154600390920154921692909190565b6002600054036117155760405162461bcd60e51b81526004016102309061395c565b6002600055603654604051635061f96960e11b81526001600160a01b0380851660048301528492169063a0c3f2d290602401602060405180830381865afa158015611764573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117889190613993565b6117a45760405162461bcd60e51b8152600401610230906139b5565b600082116117f45760405162461bcd60e51b815260206004820181905260248201527f43616e6469646174655374616b696e673a20696e76616c696420616d6f756e746044820152606401610230565b6001600160a01b0383166000908152603760205260408120600281015433929061181f908690613b43565b9050606c548110156118895760405162461bcd60e51b815260206004820152602d60248201527f43616e6469646174655374616b696e673a20696e76616c6964207374616b696e60448201526c19c8185b5bdd5b9d081b19599d609a1b6064820152608401610230565b6118948284876128f2565b61189e8386612631565b6115df5760405162461bcd60e51b815260206004820152602860248201527f43616e6469646174655374616b696e673a20636f756c64206e6f74207472616e60448201526739b332b9102927a760c11b6064820152608401610230565b6000336119106036546001600160a01b031690565b6001600160a01b0316146119365760405162461bcd60e51b815260040161023090613476565b6001600160a01b03831660009081526037602052604090206119589083612a85565b9050600061196e6036546001600160a01b031690565b905061197a8183612b23565b610da657604080518381524760208201526001600160a01b0380841692908716917f63701cd972aa3c7f87898aab145c972e52185beab07d6e39380a998d334cf6c8910160405180910390a35092915050565b6119d5612852565b6001600160a01b0316336001600160a01b031614611a055760405162461bcd60e51b815260040161023090613aee565b6000816001600160a01b03163b11611a715760405162461bcd60e51b815260206004820152602960248201527f48617356616c696461746f72436f6e74726163743a2073657420746f206e6f6e6044820152680b58dbdb9d1c9858dd60ba1b6064820152608401610230565b6110f281612697565b600260005403611a9c5760405162461bcd60e51b81526004016102309061395c565b60026000908155338152603a60205260409020546001600160a01b031615611b155760405162461bcd60e51b815260206004820152602660248201527f43616e6469646174655374616b696e673a20706f6f6c2061646d696e2069732060448201526561637469766560d01b6064820152608401610230565b3433611b2681888888888888612b7f565b6001600160a01b0380871660008181526037602081815260408084206001810180549789166001600160a01b0319988916811790915581548816871782558552603a835290842080549096168517909555929091529052611b88818385611dec565b816001600160a01b0316876001600160a01b03167ffc1f1e73948cbc47c5b7f90e5601b7daccd9ad7173218486ccc74bdd051d05e860405160405180910390a350506001600055505050505050565b33611bea6036546001600160a01b031690565b6001600160a01b031614611c105760405162461bcd60e51b815260040161023090613476565b8015610b0e576000805b82811015611d2757600060376000868685818110611c3a57611c3a613917565b9050602002016020810190611c4f9190613642565b6001600160a01b0390811682526020808301939093526040918201600090812060018101549092168152603a909352912080546001600160a01b03191690556002810154935090508215611d1457611ca78184612a85565b506001810154611cc0906001600160a01b031684612b23565b611d145760018101548154604080518681524760208201526001600160a01b0393841693909216917f7dc5115a5aba081f5a174f56a3d02eea582824783322a4ac03f7bd388f444194910160405180910390a35b5080611d1f81613943565b915050611c1a565b507f4f257d3ba23679d338f1d94296086bba5724af341b7fa31aa0ff297bfcdc62d88383604051611d59929190613b56565b60405180910390a1505050565b6000600260005403611d8a5760405162461bcd60e51b81526004016102309061395c565b6002600055611d9a338484612f2c565b9050611da63382612f8e565b600160005592915050565b6000611dbe858585612f2c565b6001600160a01b0383166000908152603760205260409020909150611de490868361278b565b949350505050565b6001830154839083906001600160a01b03808316911614611e1f5760405162461bcd60e51b8152600401610230906139fd565b82856002016000828254611e339190613b30565b92505081905550611e5985858760020154868960030154611e549190613b30565b613015565b6001600160a01b03808516600090815260058701602052604090819020429055865490519116907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d90611eaf9086815260200190565b60405180910390a25050505050565b83518214611f0757807fae52c603227f64e4c6101dde593aa9790a16b3ac77546bd746d758511e9560a5858585604051611efa93929190613bdd565b60405180910390a26122f1565b600080600080600088516001600160401b03811115611f2857611f28613901565b604051908082528060200260200182016040528015611f51578160200160208202803683370190505b509050600089516001600160401b03811115611f6f57611f6f613901565b604051908082528060200260200182016040528015611f98578160200160208202803683370190505b50905060008a516001600160401b03811115611fb657611fb6613901565b604051908082528060200260200182016040528015611fdf578160200160208202803683370190505b50905060005b8b5181101561225c578b818151811061200057612000613917565b6020908102919091018101516001600160a01b038116600090815260038084526040808320603790955290912001549097506001600160a01b03881660009081526001602081815260408084208f855290915290912001549096508a90036120a65786838961206e81613943565b9a508151811061208057612080613917565b60200260200101906001600160a01b031690816001600160a01b0316815250505061224a565b60028101548a11156120d457604080518082019091528681526020018a905260018101869055600281018a90555b60018101541561211e5760018101548c8c848181106120f5576120f5613917565b90506020020135670de0b6b3a764000061210f9190613c27565b6121199190613c3e565b612121565b60005b9850888160000160008282546121379190613b30565b91829055509050856121498a85613b43565b8151811061215957612159613917565b6020026020010181815250506040518060400160405280826000015481526020018b81525060016000896001600160a01b03166001600160a01b0316815260200190815260200160002060008c81526020019081526020016000206000820151816000015560208201518160010155905050858160010160000154146121e157600181018690555b6001810154846121f18a85613b43565b8151811061220157612201613917565b6020908102919091010152868d6122188a85613b43565b8151811061222857612228613917565b60200260200101906001600160a01b031690816001600160a01b031681525050505b8061225481613943565b915050611fe5565b5085156122a557858152858b51038b52877fee74f10cc50bf4b7e57fd36be7d46288795f3a9151dae97505b718b392ba14a38260405161229c9190613c60565b60405180910390a25b8a51156122e957877f0e54e0485f70f0f63bc25889ddbf01ce1269ad6f07fdb2df573a0fbdb4d66f888c85856040516122e093929190613c73565b60405180910390a25b505050505050505b50505050565b6001600160a01b0380851660009081526002602090815260408083209387168352929052908120600381015484900361233257549050611de4565b6001600160a01b0386166000908152600360208181526040808420600180845282862094870154865293909252832091820154839290156123bd576001600160a01b038a16600090815260016020818152604080842060038a0154855290915290912054908601549094506123a79085613b43565b85600201546123b69190613c27565b92506123c5565b846001015493505b81546000906123d5908690613b43565b6123df9089613c27565b9050670de0b6b3a76400006123f48286613b30565b6123fe9190613c3e565b865461240a9190613b30565b9b9a5050505050505050505050565b6001830154839083906001600160a01b0380831691160361244c5760405162461bcd60e51b815260040161023090613cb6565b6000831161249c5760405162461bcd60e51b815260206004820181905260248201527f44656c656761746f725374616b696e673a20696e76616c696420616d6f756e746044820152606401610230565b6001600160a01b03841660009081526004860160205260409020548311156125225760405162461bcd60e51b815260206004820152603360248201527f44656c656761746f725374616b696e673a20696e73756666696369656e7420616044820152726d6f756e7420746f20756e64656c656761746560681b6064820152608401610230565b6038546001600160a01b0385166000908152600587016020526040902054429161254b91613b30565b106125a75760405162461bcd60e51b815260206004820152602660248201527f44656c656761746f725374616b696e673a20756e64656c656761746520746f6f604482015265206561726c7960d01b6064820152608401610230565b6001600160a01b03841660009081526004860160205260409020546125e590869086906125d5908790613b43565b868960030154611e549190613b43565b84546040518481526001600160a01b03918216918616907f4d10bd049775c77bd7f255195afba5088028ecb3c7c277d393ccff7934f2f92c906020015b60405180910390a35050505050565b60008147101561268d5760405162461bcd60e51b815260206004820152602160248201527f524f4e5472616e736665723a20696e73756666696369656e742062616c616e636044820152606560f81b6064820152608401610230565b61110e8383612b23565b603680546001600160a01b0319166001600160a01b0383169081179091556040519081527fef40dc07567635f84f5edbd2f8dbc16b40d9d282dd8e7e6f4ff58236b6836169906020015b60405180910390a150565b606c8190556040518181527f372bbdb8d72373b0012f84ee5a11671e5fb72b8bea902ebca93a19cb45d32be2906020016126e1565b60388190556040518181527f4956b65267b8f1e642284bcb5037116c69a9c78d9ca576beeae0974737a4872a906020016126e1565b60398190556040518181527f02be0b73b597f2c0f138aebee162b3b0e25d5b5a26854c15dcf79176e9a1c678906020016126e1565b6001830154839083906001600160a01b038083169116036127be5760405162461bcd60e51b815260040161023090613cb6565b6001600160a01b03841660009081526004860160205260409020546127fc90869086906127ec908790613b30565b868960030154611e549190613b30565b6001600160a01b03808516600081815260058801602052604090819020429055875490519216917fe5541a6b6103d4fa7e021ed54fad39c66f27a76bd13d374cf6240ae6bd0bb72b906126229087815260200190565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103546001600160a01b031690565b6036546040805162c080c360e31b815290516000926001600160a01b03169163060406189160048083019260209291908290030181865afa1580156128c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128ed9190613a8d565b905090565b6001830154839083906001600160a01b038083169116146129255760405162461bcd60e51b8152600401610230906139fd565b846002015483111561298f5760405162461bcd60e51b815260206004820152602d60248201527f43616e6469646174655374616b696e673a20696e73756666696369656e74207360448201526c1d185ada5b99c8185b5bdd5b9d609a1b6064820152608401610230565b6038546001600160a01b038516600090815260058701602052604090205442916129b891613b30565b1115612a125760405162461bcd60e51b815260206004820152602360248201527f43616e6469646174655374616b696e673a20756e7374616b6520746f6f206561604482015262726c7960e81b6064820152608401610230565b82856002016000828254612a269190613b43565b92505081905550612a4785858760020154868960030154611e549190613b43565b84546040518481526001600160a01b03909116907f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f7590602001611eaf565b6000612a95836002015483613050565b905080836002016000828254612aab9190613b43565b9091555050600183015460028401546003850154612adc9286926001600160a01b0390911691611e54908690613b43565b82546040518281526001600160a01b03909116907f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f759060200160405180910390a292915050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612b70576040519150601f19603f3d011682016040523d82523d6000602084013e612b75565b606091505b5090949350505050565b612b8a876000612631565b612bee5760405162461bcd60e51b815260206004820152602f60248201527f43616e6469646174655374616b696e673a20706f6f6c2061646d696e2063616e60448201526e3737ba103932b1b2b4bb32902927a760891b6064820152608401610230565b612bf9846000612631565b612c5b5760405162461bcd60e51b815260206004820152602d60248201527f43616e6469646174655374616b696e673a2074726561737572792063616e6e6f60448201526c3a103932b1b2b4bb32902927a760991b6064820152608401610230565b606c54811015612cbb5760405162461bcd60e51b815260206004820152602560248201527f43616e6469646174655374616b696e673a20696e73756666696369656e7420616044820152641b5bdd5b9d60da1b6064820152608401610230565b856001600160a01b0316876001600160a01b0316148015612ced5750836001600160a01b0316866001600160a01b0316145b612d695760405162461bcd60e51b815260206004820152604160248201527f43616e6469646174655374616b696e673a20746872656520696e74657261637460448201527f696f6e20616464726573736573206d757374206265206f66207468652073616d6064820152606560f81b608482015260a401610230565b60408051600380825260808201909252600091602082016060803683370190505090508781600081518110612da057612da0613917565b60200260200101906001600160a01b031690816001600160a01b0316815250508581600181518110612dd457612dd4613917565b60200260200101906001600160a01b031690816001600160a01b0316815250508381600281518110612e0857612e08613917565b60200260200101906001600160a01b031690816001600160a01b031681525050612e3181613066565b15612ea45760405162461bcd60e51b815260206004820152603c60248201527f43616e6469646174655374616b696e673a207468726565206f7065726174696f60448201527f6e20616464726573736573206d7573742062652064697374696e6374000000006064820152608401610230565b603654604051630733ec9760e41b81526001600160a01b038981166004830152888116602483015287811660448301528681166064830152608482018690529091169063733ec9709060a401600060405180830381600087803b158015612f0a57600080fd5b505af1158015612f1e573d6000803e3d6000fd5b505050505050505050505050565b6000805b82811015612f8657612f68848483818110612f4d57612f4d613917565b9050602002016020810190612f629190613642565b8661312d565b612f729083613b30565b915080612f7e81613943565b915050612f30565b509392505050565b612f988282612631565b610b0e5760405162461bcd60e51b815260206004820152604260248201527f524f4e5472616e736665723a20756e61626c6520746f207472616e736665722060448201527f76616c75652c20726563697069656e74206d6179206861766520726576657274606482015261195960f21b608482015260a401610230565b835461302b906001600160a01b03168484613215565b60038401556001600160a01b0390911660009081526004909201602052604090912055565b600081831061305f578161110e565b5090919050565b6000815160000361307957506000919050565b60005b6001835161308a9190613b43565b81101561312457600061309e826001613b30565b90505b8351811015613111578381815181106130bc576130bc613917565b60200260200101516001600160a01b03168483815181106130df576130df613917565b60200260200101516001600160a01b0316036130ff575060019392505050565b8061310981613943565b9150506130a1565b508061311c81613943565b91505061307c565b50600092915050565b600080613138612880565b905061314a848483610c99888861121c565b9150826001600160a01b0316846001600160a01b03167f0aa4d283470c904c551d18bb894d37e17674920f3261a7f854be501e25f421b78460405161319191815260200190565b60405180910390a36001600160a01b0384811660008181526002602090815260408083209488168084529482528083208381556003808201889055858552835281842054600182015590519283529392917faa7c29611027fd4be148712bb54960253b7a7d5998c17769bfc424c2f5f185ad910160405180910390a3505092915050565b600061321f612880565b6001600160a01b038516600090815260036020526040902060018101546002820154929350909183111561329357604051806040016040528061327a886001600160a01b031660009081526037602052604090206003015490565b8152602090810185905281516001850155015160028301555b6001600160a01b0380871660009081526002602090815260408083209389168352929052908120906132c5888861121c565b905060006132d5898988856122f7565b83549091508114613327578083556040518181526001600160a01b0389811691908b16907faa7c29611027fd4be148712bb54960253b7a7d5998c17769bfc424c2f5f185ad9060200160405180910390a35b6133348584888a866133a6565b845460018085019190915560038401879055850154841461339b57886001600160a01b0316867f81faf50e2aaf52eaba2ab841071efb9f6f0850a3e7d008b1336e6001d3d4963c876001016000015460405161339291815260200190565b60405180910390a35b505050505050505050565b82846003015410156133ba57600284018190555b60006133ca856002015484613050565b905060008186600201546133de9190613b43565b9050801561346d576002860182905560018701548111156134505760405162461bcd60e51b815260206004820152602660248201527f52657761726443616c63756c6174696f6e3a20696e76616c696420706f6f6c2060448201526573686172657360d01b6064820152608401610230565b808760010160000160008282546134679190613b43565b90915550505b50505050505050565b6020808252603e908201527f48617356616c696461746f72436f6e74726163743a206d6574686f642063616c60408201527f6c6572206d7573742062652076616c696461746f7220636f6e74726163740000606082015260800190565b60008083601f8401126134e557600080fd5b5081356001600160401b038111156134fc57600080fd5b6020830191508360208260051b850101111561351757600080fd5b9250929050565b6000806000806040858703121561353457600080fd5b84356001600160401b038082111561354b57600080fd5b613557888389016134d3565b9096509450602087013591508082111561357057600080fd5b5061357d878288016134d3565b95989497509550505050565b600081518084526020808501945080840160005b838110156135b95781518752958201959082019060010161359d565b509495945050505050565b60208152600061110e6020830184613589565b6001600160a01b03811681146110f257600080fd5b60008060006040848603121561360157600080fd5b83356001600160401b0381111561361757600080fd5b613623868287016134d3565b9094509250506020840135613637816135d7565b809150509250925092565b60006020828403121561365457600080fd5b813561365f816135d7565b9392505050565b60008060008060006060868803121561367e57600080fd5b85356001600160401b038082111561369557600080fd5b6136a189838a016134d3565b909750955060208801359150808211156136ba57600080fd5b506136c7888289016134d3565b96999598509660400135949350505050565b6000806000604084860312156136ee57600080fd5b83356136f9816135d7565b925060208401356001600160401b0381111561371457600080fd5b613720868287016134d3565b9497909650939450505050565b6000806020838503121561374057600080fd5b82356001600160401b0381111561375657600080fd5b613762858286016134d3565b90969095509350505050565b6000806040838503121561378157600080fd5b823561378c816135d7565b946020939093013593505050565b600080600080608085870312156137b057600080fd5b84356137bb816135d7565b966020860135965060408601359560600135945092505050565b6000602082840312156137e757600080fd5b5035919050565b6000806040838503121561380157600080fd5b823561380c816135d7565b9150602083013561381c816135d7565b809150509250929050565b60008060006060848603121561383c57600080fd5b8335613847816135d7565b92506020840135613857816135d7565b929592945050506040919091013590565b60008060006060848603121561387d57600080fd5b8335613888816135d7565b95602085013595506040909401359392505050565b600080600080600060a086880312156138b557600080fd5b85356138c0816135d7565b945060208601356138d0816135d7565b935060408601356138e0816135d7565b925060608601356138f0816135d7565b949793965091946080013592915050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016139555761395561392d565b5060010190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000602082840312156139a557600080fd5b8151801515811461365f57600080fd5b60208082526028908201527f426173655374616b696e673a20717565727920666f72206e6f6e2d6578697374604082015267195b9d081c1bdbdb60c21b606082015260800190565b6020808252602d908201527f426173655374616b696e673a20726571756573746572206d757374206265207460408201526c3432903837b7b61030b236b4b760991b606082015260800190565b60208082526023908201527f426173655374616b696e673a207175657279207769746820656d7074792076616040820152626c756560e81b606082015260800190565b600060208284031215613a9f57600080fd5b5051919050565b60208082526028908201527f44656c656761746f725374616b696e673a20636f756c64206e6f74207472616e60408201526739b332b9102927a760c11b606082015260800190565b60208082526022908201527f48617350726f787941646d696e3a20756e617574686f72697a65642073656e6460408201526132b960f11b606082015260800190565b808201808211156111115761111161392d565b818103818111156111115761111161392d565b60208082528181018390526000908460408401835b86811015613b99578235613b7e816135d7565b6001600160a01b031682529183019190830190600101613b6b565b509695505050505050565b600081518084526020808501945080840160005b838110156135b95781516001600160a01b031687529582019590820190600101613bb8565b604081526000613bf06040830186613ba4565b82810360208401528381526001600160fb1b03841115613c0f57600080fd5b8360051b808660208401370160200195945050505050565b80820281158282048414176111115761111161392d565b600082613c5b57634e487b7160e01b600052601260045260246000fd5b500490565b60208152600061110e6020830184613ba4565b606081526000613c866060830186613ba4565b8281036020840152613c988186613589565b90508281036040840152613cac8185613589565b9695505050505050565b60208082526031908201527f426173655374616b696e673a2064656c656761746f72206d757374206e6f74206040820152703132903a3432903837b7b61030b236b4b760791b60608201526080019056fea2646970667358221220e83be7b4fb217626c75492f6661dab51328551fb354334680cab37b9f5d5b0cf64736f6c63430008110033", "devdoc": { "kind": "dev", "methods": { @@ -1094,6 +1113,9 @@ "getManyStakingTotals(address[])": { "details": "Returns the total staking amounts of all users for the pools `_poolAddrs`." }, + "getPoolAddressOf(address)": { + "details": "Returns the consensus address corresponding to the pool admin." + }, "getReward(address,address)": { "details": "Returns the reward amount that user claimable." }, @@ -1176,31 +1198,31 @@ "type": "t_uint256" }, { - "astId": 25469, + "astId": 25497, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "_accumulatedRps", "offset": 0, "slot": "1", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(PeriodWrapper)10082_storage))" + "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(PeriodWrapper)10088_storage))" }, { - "astId": 25477, + "astId": 25505, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "_userReward", "offset": 0, "slot": "2", - "type": "t_mapping(t_address,t_mapping(t_address,t_struct(UserRewardFields)10717_storage))" + "type": "t_mapping(t_address,t_mapping(t_address,t_struct(UserRewardFields)10731_storage))" }, { - "astId": 25483, + "astId": 25511, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "_stakingPool", "offset": 0, "slot": "3", - "type": "t_mapping(t_address,t_struct(PoolFields)10723_storage)" + "type": "t_mapping(t_address,t_struct(PoolFields)10737_storage)" }, { - "astId": 25488, + "astId": 25516, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "______gap", "offset": 0, @@ -1213,18 +1235,18 @@ "label": "_validatorContract", "offset": 0, "slot": "54", - "type": "t_contract(IRoninValidatorSet)11221" + "type": "t_contract(IRoninValidatorSet)11235" }, { - "astId": 24017, + "astId": 24031, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "_stakingPool", "offset": 0, "slot": "55", - "type": "t_mapping(t_address,t_struct(PoolDetail)10447_storage)" + "type": "t_mapping(t_address,t_struct(PoolDetail)10453_storage)" }, { - "astId": 24020, + "astId": 24034, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "_cooldownSecsToUndelegate", "offset": 0, @@ -1232,7 +1254,7 @@ "type": "t_uint256" }, { - "astId": 24023, + "astId": 24037, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "_waitingSecsToRevoke", "offset": 0, @@ -1240,7 +1262,7 @@ "type": "t_uint256" }, { - "astId": 24028, + "astId": 24042, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "_activePoolAdminMapping", "offset": 0, @@ -1248,7 +1270,7 @@ "type": "t_mapping(t_address,t_address)" }, { - "astId": 24033, + "astId": 24047, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "______gap", "offset": 0, @@ -1256,7 +1278,7 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 24375, + "astId": 24403, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "_minValidatorStakingAmount", "offset": 0, @@ -1264,7 +1286,7 @@ "type": "t_uint256" }, { - "astId": 24380, + "astId": 24408, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "______gap", "offset": 0, @@ -1272,7 +1294,7 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 24976, + "astId": 25004, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "______gap", "offset": 0, @@ -1319,7 +1341,7 @@ "label": "bool", "numberOfBytes": "1" }, - "t_contract(IRoninValidatorSet)11221": { + "t_contract(IRoninValidatorSet)11235": { "encoding": "inplace", "label": "contract IRoninValidatorSet", "numberOfBytes": "20" @@ -1331,40 +1353,40 @@ "numberOfBytes": "32", "value": "t_address" }, - "t_mapping(t_address,t_mapping(t_address,t_struct(UserRewardFields)10717_storage))": { + "t_mapping(t_address,t_mapping(t_address,t_struct(UserRewardFields)10731_storage))": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => mapping(address => struct IRewardPool.UserRewardFields))", "numberOfBytes": "32", - "value": "t_mapping(t_address,t_struct(UserRewardFields)10717_storage)" + "value": "t_mapping(t_address,t_struct(UserRewardFields)10731_storage)" }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(PeriodWrapper)10082_storage))": { + "t_mapping(t_address,t_mapping(t_uint256,t_struct(PeriodWrapper)10088_storage))": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => mapping(uint256 => struct PeriodWrapperConsumer.PeriodWrapper))", "numberOfBytes": "32", - "value": "t_mapping(t_uint256,t_struct(PeriodWrapper)10082_storage)" + "value": "t_mapping(t_uint256,t_struct(PeriodWrapper)10088_storage)" }, - "t_mapping(t_address,t_struct(PoolDetail)10447_storage)": { + "t_mapping(t_address,t_struct(PoolDetail)10453_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct IBaseStaking.PoolDetail)", "numberOfBytes": "32", - "value": "t_struct(PoolDetail)10447_storage" + "value": "t_struct(PoolDetail)10453_storage" }, - "t_mapping(t_address,t_struct(PoolFields)10723_storage)": { + "t_mapping(t_address,t_struct(PoolFields)10737_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct IRewardPool.PoolFields)", "numberOfBytes": "32", - "value": "t_struct(PoolFields)10723_storage" + "value": "t_struct(PoolFields)10737_storage" }, - "t_mapping(t_address,t_struct(UserRewardFields)10717_storage)": { + "t_mapping(t_address,t_struct(UserRewardFields)10731_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct IRewardPool.UserRewardFields)", "numberOfBytes": "32", - "value": "t_struct(UserRewardFields)10717_storage" + "value": "t_struct(UserRewardFields)10731_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -1373,19 +1395,19 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_mapping(t_uint256,t_struct(PeriodWrapper)10082_storage)": { + "t_mapping(t_uint256,t_struct(PeriodWrapper)10088_storage)": { "encoding": "mapping", "key": "t_uint256", "label": "mapping(uint256 => struct PeriodWrapperConsumer.PeriodWrapper)", "numberOfBytes": "32", - "value": "t_struct(PeriodWrapper)10082_storage" + "value": "t_struct(PeriodWrapper)10088_storage" }, - "t_struct(PeriodWrapper)10082_storage": { + "t_struct(PeriodWrapper)10088_storage": { "encoding": "inplace", "label": "struct PeriodWrapperConsumer.PeriodWrapper", "members": [ { - "astId": 10079, + "astId": 10085, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "inner", "offset": 0, @@ -1393,7 +1415,7 @@ "type": "t_uint256" }, { - "astId": 10081, + "astId": 10087, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "lastPeriod", "offset": 0, @@ -1403,12 +1425,12 @@ ], "numberOfBytes": "64" }, - "t_struct(PoolDetail)10447_storage": { + "t_struct(PoolDetail)10453_storage": { "encoding": "inplace", "label": "struct IBaseStaking.PoolDetail", "members": [ { - "astId": 10432, + "astId": 10438, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "addr", "offset": 0, @@ -1416,7 +1438,7 @@ "type": "t_address" }, { - "astId": 10434, + "astId": 10440, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "admin", "offset": 0, @@ -1424,7 +1446,7 @@ "type": "t_address" }, { - "astId": 10436, + "astId": 10442, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "stakingAmount", "offset": 0, @@ -1432,7 +1454,7 @@ "type": "t_uint256" }, { - "astId": 10438, + "astId": 10444, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "stakingTotal", "offset": 0, @@ -1440,7 +1462,7 @@ "type": "t_uint256" }, { - "astId": 10442, + "astId": 10448, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "delegatingAmount", "offset": 0, @@ -1448,7 +1470,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 10446, + "astId": 10452, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "lastDelegatingTimestamp", "offset": 0, @@ -1458,12 +1480,12 @@ ], "numberOfBytes": "192" }, - "t_struct(PoolFields)10723_storage": { + "t_struct(PoolFields)10737_storage": { "encoding": "inplace", "label": "struct IRewardPool.PoolFields", "members": [ { - "astId": 10719, + "astId": 10733, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "aRps", "offset": 0, @@ -1471,22 +1493,22 @@ "type": "t_uint256" }, { - "astId": 10722, + "astId": 10736, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "shares", "offset": 0, "slot": "1", - "type": "t_struct(PeriodWrapper)10082_storage" + "type": "t_struct(PeriodWrapper)10088_storage" } ], "numberOfBytes": "96" }, - "t_struct(UserRewardFields)10717_storage": { + "t_struct(UserRewardFields)10731_storage": { "encoding": "inplace", "label": "struct IRewardPool.UserRewardFields", "members": [ { - "astId": 10710, + "astId": 10724, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "debited", "offset": 0, @@ -1494,7 +1516,7 @@ "type": "t_uint256" }, { - "astId": 10712, + "astId": 10726, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "aRps", "offset": 0, @@ -1502,7 +1524,7 @@ "type": "t_uint256" }, { - "astId": 10714, + "astId": 10728, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "minAmount", "offset": 0, @@ -1510,7 +1532,7 @@ "type": "t_uint256" }, { - "astId": 10716, + "astId": 10730, "contract": "contracts/ronin/staking/Staking.sol:Staking", "label": "lastPeriod", "offset": 0, diff --git a/deployments/ronin-testnet/solcInputs/9c14b324033beb5ee990c4b68d9e780e.json b/deployments/ronin-testnet/solcInputs/9c14b324033beb5ee990c4b68d9e780e.json new file mode 100644 index 000000000..0c8fe8cad --- /dev/null +++ b/deployments/ronin-testnet/solcInputs/9c14b324033beb5ee990c4b68d9e780e.json @@ -0,0 +1,485 @@ +{ + "language": "Solidity", + "sources": { + "contracts/extensions/collections/HasBridgeContract.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./HasProxyAdmin.sol\";\nimport \"../../interfaces/collections/IHasBridgeContract.sol\";\nimport \"../../interfaces/IBridge.sol\";\n\ncontract HasBridgeContract is IHasBridgeContract, HasProxyAdmin {\n IBridge internal _bridgeContract;\n\n modifier onlyBridgeContract() {\n require(bridgeContract() == msg.sender, \"HasBridgeContract: method caller must be bridge contract\");\n _;\n }\n\n /**\n * @inheritdoc IHasBridgeContract\n */\n function bridgeContract() public view override returns (address) {\n return address(_bridgeContract);\n }\n\n /**\n * @inheritdoc IHasBridgeContract\n */\n function setBridgeContract(address _addr) external virtual override onlyAdmin {\n require(_addr.code.length > 0, \"HasBridgeContract: set to non-contract\");\n _setBridgeContract(_addr);\n }\n\n /**\n * @dev Sets the bridge contract.\n *\n * Emits the event `BridgeContractUpdated`.\n *\n */\n function _setBridgeContract(address _addr) internal {\n _bridgeContract = IBridge(_addr);\n emit BridgeContractUpdated(_addr);\n }\n}\n" + }, + "contracts/extensions/collections/HasProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/utils/StorageSlot.sol\";\n\nabstract contract HasProxyAdmin {\n // bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n modifier onlyAdmin() {\n require(msg.sender == _getAdmin(), \"HasProxyAdmin: unauthorized sender\");\n _;\n }\n\n /**\n * @dev Returns proxy admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n}\n" + }, + "contracts/interfaces/collections/IHasBridgeContract.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface IHasBridgeContract {\n /// @dev Emitted when the bridge contract is updated.\n event BridgeContractUpdated(address);\n\n /**\n * @dev Returns the bridge contract.\n */\n function bridgeContract() external view returns (address);\n\n /**\n * @dev Sets the bridge contract.\n *\n * Requirements:\n * - The method caller is admin.\n * - The new address is a contract.\n *\n * Emits the event `BridgeContractUpdated`.\n *\n */\n function setBridgeContract(address) external;\n}\n" + }, + "contracts/interfaces/IBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IBridge {\n /**\n * @dev Replaces the old bridge operator list by the new one.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emitted the event `BridgeOperatorsReplaced`.\n *\n */\n function replaceBridgeOperators(address[] calldata) external;\n\n /**\n * @dev Returns the bridge operator list.\n */\n function getBridgeOperators() external view returns (address[] memory);\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "contracts/ronin/BridgeTracking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport \"../extensions/collections/HasBridgeContract.sol\";\nimport \"../extensions/collections/HasValidatorContract.sol\";\nimport \"../interfaces/IBridgeTracking.sol\";\n\ncontract BridgeTracking is HasBridgeContract, HasValidatorContract, Initializable, IBridgeTracking {\n struct VoteStats {\n uint256 totalVotes;\n uint256 totalBallots;\n mapping(address => uint256) totalBallotsOf;\n address[] voters;\n }\n\n struct VoteStatsTimeWrapper {\n uint256 lastEpoch;\n VoteStats info;\n }\n\n struct ReceiptStats {\n // The period that the receipt is approved\n uint256 approvedPeriod;\n // The address list of voters\n address[] voters;\n // Mapping from voter => flag indicating the voter casts vote for this receipt\n mapping(address => bool) voted;\n }\n\n /// @dev Deprecated slots.\n uint256[6] private __deprecated;\n\n /// @dev The block that the contract allows incoming mutable calls.\n uint256 public startedAtBlock;\n\n /// @dev The temporary info of votes and ballots\n VoteStatsTimeWrapper internal _temporaryStats;\n /// @dev Mapping from period number => vote stats based on period\n mapping(uint256 => VoteStats) internal _periodStats;\n /// @dev Mapping from vote kind => receipt id => receipt stats\n mapping(VoteKind => mapping(uint256 => ReceiptStats)) internal _receiptStats;\n\n modifier skipOnUnstarted() {\n if (block.number < startedAtBlock) {\n return;\n }\n _;\n }\n\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @dev Initializes the contract storage.\n */\n function initialize(\n address _bridgeContract,\n address _validatorContract,\n uint256 _startedAtBlock\n ) external initializer {\n _setBridgeContract(_bridgeContract);\n _setValidatorContract(_validatorContract);\n startedAtBlock = _startedAtBlock;\n }\n\n /**\n * @inheritdoc IBridgeTracking\n */\n function totalVotes(uint256 _period) external view override returns (uint256 _totalVotes) {\n _totalVotes = _periodStats[_period].totalVotes;\n\n bool _mustCountLastStats = _isLastStatsCountedForPeriod(_period);\n if (_mustCountLastStats) {\n _totalVotes += _temporaryStats.info.totalVotes;\n }\n }\n\n /**\n * @inheritdoc IBridgeTracking\n */\n function totalBallots(uint256 _period) external view override returns (uint256 _totalBallots) {\n _totalBallots = _periodStats[_period].totalBallots;\n\n bool _mustCountLastStats = _isLastStatsCountedForPeriod(_period);\n if (_mustCountLastStats) {\n _totalBallots += _temporaryStats.info.totalBallots;\n }\n }\n\n /**\n * @inheritdoc IBridgeTracking\n */\n function getManyTotalBallots(uint256 _period, address[] calldata _bridgeOperators)\n external\n view\n override\n returns (uint256[] memory _res)\n {\n _res = new uint256[](_bridgeOperators.length);\n bool _mustCountLastStats = _isLastStatsCountedForPeriod(_period);\n for (uint _i = 0; _i < _bridgeOperators.length; _i++) {\n _res[_i] = _totalBallotsOf(_period, _bridgeOperators[_i], _mustCountLastStats);\n }\n }\n\n /**\n * @inheritdoc IBridgeTracking\n */\n function totalBallotsOf(uint256 _period, address _bridgeOperator) public view override returns (uint256) {\n return _totalBallotsOf(_period, _bridgeOperator, _isLastStatsCountedForPeriod(_period));\n }\n\n /**\n * @inheritdoc IBridgeTracking\n */\n function handleVoteApproved(VoteKind _kind, uint256 _requestId) external override onlyBridgeContract skipOnUnstarted {\n ReceiptStats storage _stats = _receiptStats[_kind][_requestId];\n\n // Only records for the receipt which not approved\n if (_stats.approvedPeriod == 0) {\n _trySyncPeriodStats();\n uint256 _currentPeriod = _validatorContract.currentPeriod();\n _temporaryStats.info.totalVotes++;\n _stats.approvedPeriod = _currentPeriod;\n\n address[] storage _voters = _stats.voters;\n for (uint _i = 0; _i < _voters.length; _i++) {\n _increaseBallot(_kind, _requestId, _voters[_i], _currentPeriod);\n }\n\n delete _stats.voters;\n }\n }\n\n /**\n * @inheritdoc IBridgeTracking\n */\n function recordVote(\n VoteKind _kind,\n uint256 _requestId,\n address _operator\n ) external override onlyBridgeContract skipOnUnstarted {\n uint256 _period = _validatorContract.currentPeriod();\n _trySyncPeriodStats();\n ReceiptStats storage _stats = _receiptStats[_kind][_requestId];\n\n // Stores the ones vote for the (deposit/mainchain withdrawal) request which is not approved yet\n if (_stats.approvedPeriod == 0) {\n _stats.voters.push(_operator);\n return;\n }\n\n _increaseBallot(_kind, _requestId, _operator, _period);\n }\n\n /**\n * Increases the ballot for the operator at a period.\n */\n function _increaseBallot(\n VoteKind _kind,\n uint256 _requestId,\n address _operator,\n uint256 _period\n ) internal {\n ReceiptStats storage _receiptInfo = _receiptStats[_kind][_requestId];\n if (_receiptInfo.voted[_operator]) {\n return;\n }\n\n _receiptInfo.voted[_operator] = true;\n\n // Only records within a period\n if (_receiptInfo.approvedPeriod == _period) {\n if (_temporaryStats.info.totalBallotsOf[_operator] == 0) {\n _temporaryStats.info.voters.push(_operator);\n }\n _temporaryStats.info.totalBallots++;\n _temporaryStats.info.totalBallotsOf[_operator]++;\n }\n }\n\n /**\n * @dev See `totalBallotsOf`.\n */\n function _totalBallotsOf(\n uint256 _period,\n address _bridgeOperator,\n bool _mustCountLastStats\n ) internal view returns (uint256 _totalBallots) {\n _totalBallots = _periodStats[_period].totalBallotsOf[_bridgeOperator];\n if (_mustCountLastStats) {\n _totalBallots += _temporaryStats.info.totalBallotsOf[_bridgeOperator];\n }\n }\n\n /**\n * @dev Syncs period stats if the last epoch + 1 is already wrapped up.\n */\n function _trySyncPeriodStats() internal {\n uint256 _currentEpoch = _validatorContract.epochOf(block.number);\n if (_temporaryStats.lastEpoch < _currentEpoch) {\n (bool _filled, uint256 _period) = _validatorContract.tryGetPeriodOfEpoch(_temporaryStats.lastEpoch + 1);\n if (!_filled) {\n return;\n }\n\n VoteStats storage _stats = _periodStats[_period];\n _stats.totalVotes += _temporaryStats.info.totalVotes;\n _stats.totalBallots += _temporaryStats.info.totalBallots;\n\n address _voter;\n for (uint _i = 0; _i < _temporaryStats.info.voters.length; _i++) {\n _voter = _temporaryStats.info.voters[_i];\n _stats.totalBallotsOf[_voter] += _temporaryStats.info.totalBallotsOf[_voter];\n delete _temporaryStats.info.totalBallotsOf[_voter];\n }\n delete _temporaryStats.info;\n _temporaryStats.lastEpoch = _currentEpoch;\n }\n }\n\n /**\n * @dev Returns whether the last stats must be counted or not;\n */\n function _isLastStatsCountedForPeriod(uint256 _queriedPeriod) internal view returns (bool) {\n uint256 _currentEpoch = _validatorContract.epochOf(block.number);\n (bool _filled, uint256 _periodOfNextTemporaryEpoch) = _validatorContract.tryGetPeriodOfEpoch(\n _temporaryStats.lastEpoch + 1\n );\n return _filled && _queriedPeriod == _periodOfNextTemporaryEpoch && _temporaryStats.lastEpoch < _currentEpoch;\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "contracts/extensions/collections/HasValidatorContract.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./HasProxyAdmin.sol\";\nimport \"../../interfaces/collections/IHasValidatorContract.sol\";\nimport \"../../interfaces/validator/IRoninValidatorSet.sol\";\n\ncontract HasValidatorContract is IHasValidatorContract, HasProxyAdmin {\n IRoninValidatorSet internal _validatorContract;\n\n modifier onlyValidatorContract() {\n require(validatorContract() == msg.sender, \"HasValidatorContract: method caller must be validator contract\");\n _;\n }\n\n /**\n * @inheritdoc IHasValidatorContract\n */\n function validatorContract() public view override returns (address) {\n return address(_validatorContract);\n }\n\n /**\n * @inheritdoc IHasValidatorContract\n */\n function setValidatorContract(address _addr) external override onlyAdmin {\n require(_addr.code.length > 0, \"HasValidatorContract: set to non-contract\");\n _setValidatorContract(_addr);\n }\n\n /**\n * @dev Sets the validator contract.\n *\n * Emits the event `ValidatorContractUpdated`.\n *\n */\n function _setValidatorContract(address _addr) internal {\n _validatorContract = IRoninValidatorSet(_addr);\n emit ValidatorContractUpdated(_addr);\n }\n}\n" + }, + "contracts/interfaces/IBridgeTracking.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IBridgeTracking {\n enum VoteKind {\n Deposit,\n Withdrawal,\n MainchainWithdrawal\n }\n\n /**\n * @dev Returns the total number of votes at the specific period `_period`.\n */\n function totalVotes(uint256 _period) external view returns (uint256);\n\n /**\n * @dev Returns the total number of ballots at the specific period `_period`.\n */\n function totalBallots(uint256 _period) external view returns (uint256);\n\n /**\n * @dev Returns the total number of ballots of bridge operators at the specific period `_period`.\n */\n function getManyTotalBallots(uint256 _period, address[] calldata _bridgeOperators)\n external\n view\n returns (uint256[] memory);\n\n /**\n * @dev Returns the total number of ballots of a bridge operator at the specific period `_period`.\n */\n function totalBallotsOf(uint256 _period, address _bridgeOperator) external view returns (uint256);\n\n /**\n * @dev Handles the request once it is approved.\n *\n * Requirements:\n * - The method caller is the bridge contract.\n *\n */\n function handleVoteApproved(VoteKind _kind, uint256 _requestId) external;\n\n /**\n * @dev Records vote for a receipt and a operator.\n *\n * Requirements:\n * - The method caller is the bridge contract.\n *\n */\n function recordVote(\n VoteKind _kind,\n uint256 _requestId,\n address _operator\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/interfaces/collections/IHasValidatorContract.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface IHasValidatorContract {\n /// @dev Emitted when the validator contract is updated.\n event ValidatorContractUpdated(address);\n\n /**\n * @dev Returns the validator contract.\n */\n function validatorContract() external view returns (address);\n\n /**\n * @dev Sets the validator contract.\n *\n * Requirements:\n * - The method caller is admin.\n * - The new address is a contract.\n *\n * Emits the event `ValidatorContractUpdated`.\n *\n */\n function setValidatorContract(address) external;\n}\n" + }, + "contracts/interfaces/validator/IRoninValidatorSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"./ICandidateManager.sol\";\nimport \"./info-fragments/ICommonInfo.sol\";\nimport \"./ICoinbaseExecution.sol\";\nimport \"./ISlashingExecution.sol\";\n\ninterface IRoninValidatorSet is ICandidateManager, ICommonInfo, ISlashingExecution, ICoinbaseExecution {}\n" + }, + "contracts/interfaces/validator/ICandidateManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface ICandidateManager {\n struct ValidatorCandidate {\n // Admin of the candidate\n address admin;\n // Address of the validator that produces block, e.g. block.coinbase. This is so-called validator address.\n address consensusAddr;\n // Address that receives mining reward of the validator\n address payable treasuryAddr;\n // Address of the bridge operator corresponding to the candidate\n address bridgeOperatorAddr;\n // The percentage of reward that validators can be received, the rest goes to the delegators.\n // Values in range [0; 100_00] stands for 0-100%\n uint256 commissionRate;\n // The timestamp that scheduled to revoke the candidate (no schedule=0)\n uint256 revokingTimestamp;\n // The deadline that the candidate must top up staking amount to keep it larger than or equal to the threshold (no deadline=0)\n uint256 topupDeadline;\n }\n\n struct CommissionSchedule {\n // The timestamp that the commission schedule gets affected (no schedule=0).\n uint256 effectiveTimestamp;\n // The new commission rate. Value is in range [0; 100_00], stands for 0-100%\n uint256 commissionRate;\n }\n\n /// @dev Emitted when the maximum number of validator candidates is updated.\n event MaxValidatorCandidateUpdated(uint256 threshold);\n /// @dev Emitted when the min offset to the effective date of commission rate change is updated.\n event MinEffectiveDaysOnwardsUpdated(uint256 numOfDays);\n /// @dev Emitted when the validator candidate is granted.\n event CandidateGranted(\n address indexed consensusAddr,\n address indexed treasuryAddr,\n address indexed admin,\n address bridgeOperator\n );\n /// @dev Emitted when the revoking timestamp of a candidate is updated.\n event CandidateRevokingTimestampUpdated(address indexed consensusAddr, uint256 revokingTimestamp);\n /// @dev Emitted when the topup deadline of a candidate is updated.\n event CandidateTopupDeadlineUpdated(address indexed consensusAddr, uint256 topupDeadline);\n /// @dev Emitted when the validator candidate is revoked.\n event CandidatesRevoked(address[] consensusAddrs);\n\n /// @dev Emitted when a schedule for updating commission rate is set.\n event CommissionRateUpdateScheduled(address indexed consensusAddr, uint256 effectiveTimestamp, uint256 rate);\n /// @dev Emitted when the commission rate of a validator is updated.\n event CommissionRateUpdated(address indexed consensusAddr, uint256 rate);\n\n /**\n * @dev Returns the maximum number of validator candidate.\n */\n function maxValidatorCandidate() external view returns (uint256);\n\n /**\n * @dev Returns the minimum number of days to the effective date of commission rate change.\n */\n function minEffectiveDaysOnwards() external view returns (uint256);\n\n /**\n * @dev Sets the maximum number of validator candidate.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the `MaxValidatorCandidateUpdated` event.\n *\n */\n function setMaxValidatorCandidate(uint256) external;\n\n /**\n * @dev Sets the minimum number of days to the effective date of commision rate change.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the `MinEffectiveDaysOnwardsUpdated` event.\n *\n */\n function setMinEffectiveDaysOnwards(uint256 _numOfDays) external;\n\n /**\n * @dev Grants a validator candidate.\n *\n * Requirements:\n * - The method caller is staking contract.\n *\n * Emits the event `CandidateGranted`.\n *\n */\n function grantValidatorCandidate(\n address _admin,\n address _consensusAddr,\n address payable _treasuryAddr,\n address _bridgeOperatorAddr,\n uint256 _commissionRate\n ) external;\n\n /**\n * @dev Requests to revoke a validator candidate in next `_secsLeft` seconds.\n *\n * Requirements:\n * - The method caller is staking contract.\n *\n * Emits the event `CandidateRevokingTimestampUpdated`.\n *\n */\n function requestRevokeCandidate(address, uint256 _secsLeft) external;\n\n /**\n * @dev Fallback function of `CandidateStaking-requestUpdateCommissionRate`.\n *\n * Requirements:\n * - The method caller is the staking contract.\n * - The `_effectiveTimestamp` must be the beginning of a UTC day, and at least from 7 days onwards\n * - The `_rate` must be in range of [0_00; 100_00].\n *\n * Emits the event `CommissionRateUpdateScheduled`.\n *\n */\n function execRequestUpdateCommissionRate(\n address _consensusAddr,\n uint256 _effectiveTimestamp,\n uint256 _rate\n ) external;\n\n /**\n * @dev Returns whether the address is a validator (candidate).\n */\n function isValidatorCandidate(address _addr) external view returns (bool);\n\n /**\n * @dev Returns the validator candidate.\n */\n function getValidatorCandidates() external view returns (address[] memory);\n\n /**\n * @dev Returns all candidate info.\n */\n function getCandidateInfos() external view returns (ValidatorCandidate[] memory);\n\n /**\n * @dev Returns the info of a candidate.\n */\n function getCandidateInfo(address _candidate) external view returns (ValidatorCandidate memory);\n\n /**\n * @dev Returns whether the address is the candidate admin.\n */\n function isCandidateAdmin(address _candidate, address _admin) external view returns (bool);\n\n /**\n * @dev Returns the schedule of changing commission rate of a candidate address.\n */\n function getCommissionChangeSchedule(address _candidate) external view returns (CommissionSchedule memory);\n}\n" + }, + "contracts/interfaces/validator/info-fragments/ICommonInfo.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"./IJailingInfo.sol\";\nimport \"./ITimingInfo.sol\";\nimport \"./IValidatorInfo.sol\";\n\ninterface ICommonInfo is ITimingInfo, IJailingInfo, IValidatorInfo {\n /// @dev Emitted when the deprecated reward is withdrawn.\n event DeprecatedRewardRecycled(address indexed recipientAddr, uint256 amount);\n /// @dev Emitted when the deprecated reward withdrawal is failed\n event DeprecatedRewardRecycleFailed(address indexed recipientAddr, uint256 amount, uint256 balance);\n\n /**\n * @dev Returns the total deprecated reward, which includes reward that is not sent for slashed validators and unsastified bridge operators\n */\n function totalDeprecatedReward() external view returns (uint256);\n}\n" + }, + "contracts/interfaces/validator/ICoinbaseExecution.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"./ISlashingExecution.sol\";\n\ninterface ICoinbaseExecution is ISlashingExecution {\n enum BlockRewardDeprecatedType {\n UNKNOWN,\n UNAVAILABILITY,\n AFTER_BAILOUT\n }\n\n /// @dev Emitted when the validator set is updated\n event ValidatorSetUpdated(uint256 indexed period, address[] consensusAddrs);\n /// @dev Emitted when the bridge operator set is updated, to mirror the in-jail and maintaining status of the validator.\n event BlockProducerSetUpdated(uint256 indexed period, address[] consensusAddrs);\n /// @dev Emitted when the bridge operator set is updated.\n event BridgeOperatorSetUpdated(uint256 indexed period, address[] bridgeOperators);\n\n /// @dev Emitted when the reward of the block producer is deprecated.\n event BlockRewardDeprecated(\n address indexed coinbaseAddr,\n uint256 rewardAmount,\n BlockRewardDeprecatedType deprecatedType\n );\n /// @dev Emitted when the block reward is submitted.\n event BlockRewardSubmitted(address indexed coinbaseAddr, uint256 submittedAmount, uint256 bonusAmount);\n\n /// @dev Emitted when the block producer reward is distributed.\n event MiningRewardDistributed(address indexed consensusAddr, address indexed recipient, uint256 amount);\n /// @dev Emitted when the contract fails when distributing the block producer reward.\n event MiningRewardDistributionFailed(\n address indexed consensusAddr,\n address indexed recipient,\n uint256 amount,\n uint256 contractBalance\n );\n\n /// @dev Emitted when the bridge operator reward is distributed.\n event BridgeOperatorRewardDistributed(\n address indexed consensusAddr,\n address indexed bridgeOperator,\n address indexed recipientAddr,\n uint256 amount\n );\n /// @dev Emitted when the contract fails when distributing the bridge operator reward.\n event BridgeOperatorRewardDistributionFailed(\n address indexed consensusAddr,\n address indexed bridgeOperator,\n address indexed recipient,\n uint256 amount,\n uint256 contractBalance\n );\n\n /// @dev Emitted when the amount of RON reward is distributed to staking contract.\n event StakingRewardDistributed(uint256 amount);\n /// @dev Emitted when the contracts fails when distributing the amount of RON to the staking contract.\n event StakingRewardDistributionFailed(uint256 amount, uint256 contractBalance);\n\n /// @dev Emitted when the epoch is wrapped up.\n event WrappedUpEpoch(uint256 indexed periodNumber, uint256 indexed epochNumber, bool periodEnding);\n\n /**\n * @dev Submits reward of the current block.\n *\n * Requirements:\n * - The method caller is coinbase.\n *\n * Emits the event `MiningRewardDeprecated` if the coinbase is slashed or no longer be a block producer.\n * Emits the event `BlockRewardSubmitted` for the valid call.\n *\n */\n function submitBlockReward() external payable;\n\n /**\n * @dev Wraps up the current epoch.\n *\n * Requirements:\n * - The method must be called when the current epoch is ending.\n * - The epoch is not wrapped yet.\n * - The method caller is coinbase.\n *\n * Emits the event `MiningRewardDistributed` when some validator has reward distributed.\n * Emits the event `StakingRewardDistributed` when some staking pool has reward distributed.\n * Emits the event `BlockProducerSetUpdated` when the epoch is wrapped up.\n * Emits the event `BridgeOperatorSetUpdated` when the epoch is wrapped up at period ending.\n * Emits the event `ValidatorSetUpdated` when the epoch is wrapped up at period ending, and the validator set gets updated.\n * Emits the event `WrappedUpEpoch`.\n *\n */\n function wrapUpEpoch() external payable;\n}\n" + }, + "contracts/interfaces/validator/ISlashingExecution.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface ISlashingExecution {\n /// @dev Emitted when the validator is punished.\n event ValidatorPunished(\n address indexed consensusAddr,\n uint256 indexed period,\n uint256 jailedUntil,\n uint256 deductedStakingAmount,\n bool blockProducerRewardDeprecated,\n bool bridgeOperatorRewardDeprecated\n );\n /// @dev Emitted when the validator get out of jail by bailout.\n event ValidatorUnjailed(address indexed validator, uint256 period);\n\n /**\n * @dev Finalize the slash request from slash indicator contract.\n *\n * Requirements:\n * - The method caller is slash indicator contract.\n *\n * Emits the event `ValidatorPunished`.\n *\n */\n function execSlash(\n address _validatorAddr,\n uint256 _newJailedUntil,\n uint256 _slashAmount\n ) external;\n\n /**\n * @dev Finalize the bailout request from slash indicator contract.\n *\n * Requirements:\n * - The method caller is slash indicator contract.\n *\n * Emits the event `ValidatorUnjailed`.\n *\n */\n function execBailOut(address _validatorAddr, uint256 _period) external;\n}\n" + }, + "contracts/interfaces/validator/info-fragments/IJailingInfo.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface IJailingInfo {\n /**\n * @dev Returns whether the validator are put in jail (cannot join the set of validators) during the current period.\n */\n function checkJailed(address) external view returns (bool);\n\n /**\n * @dev Returns whether the validator are put in jail and the number of block and epoch that he still is in the jail.\n */\n function getJailedTimeLeft(address _addr)\n external\n view\n returns (\n bool isJailed_,\n uint256 blockLeft_,\n uint256 epochLeft_\n );\n\n /**\n * @dev Returns whether the validator are put in jail (cannot join the set of validators) at a specific block.\n */\n function checkJailedAtBlock(address _addr, uint256 _blockNum) external view returns (bool);\n\n /**\n * @dev Returns whether the validator are put in jail at a specific block and the number of block and epoch that he still is in the jail.\n */\n function getJailedTimeLeftAtBlock(address _addr, uint256 _blockNum)\n external\n view\n returns (\n bool isJailed_,\n uint256 blockLeft_,\n uint256 epochLeft_\n );\n\n /**\n * @dev Returns whether the validators are put in jail (cannot join the set of validators) during the current period.\n */\n function checkManyJailed(address[] calldata) external view returns (bool[] memory);\n\n /**\n * @dev Returns whether the incoming reward of the block producers are deprecated during the current period.\n */\n function checkMiningRewardDeprecated(address[] calldata _blockProducers) external view returns (bool[] memory);\n\n /**\n * @dev Returns whether the incoming reward of the block producers are deprecated during a specific period.\n */\n function checkMiningRewardDeprecatedAtPeriod(address[] calldata _blockProducers, uint256 _period)\n external\n view\n returns (bool[] memory);\n}\n" + }, + "contracts/interfaces/validator/info-fragments/ITimingInfo.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface ITimingInfo {\n /**\n * @dev Returns the block that validator set was updated.\n */\n function getLastUpdatedBlock() external view returns (uint256);\n\n /**\n * @dev Returns the number of blocks in a epoch.\n */\n function numberOfBlocksInEpoch() external view returns (uint256 _numberOfBlocks);\n\n /**\n * @dev Returns the epoch index from the block number.\n */\n function epochOf(uint256 _block) external view returns (uint256);\n\n /**\n * @dev Returns whether the epoch ending is at the block number `_block`.\n */\n function epochEndingAt(uint256 _block) external view returns (bool);\n\n /**\n * @dev Tries to get the period index from the epoch number.\n */\n function tryGetPeriodOfEpoch(uint256 _epoch) external view returns (bool _filled, uint256 _periodNumber);\n\n /**\n * @dev Returns whether the period ending at the current block number.\n */\n function isPeriodEnding() external view returns (bool);\n\n /**\n * @dev Returns the period index from the current block.\n */\n function currentPeriod() external view returns (uint256);\n\n /**\n * @dev Returns the block number that the current period starts at.\n */\n function currentPeriodStartAtBlock() external view returns (uint256);\n}\n" + }, + "contracts/interfaces/validator/info-fragments/IValidatorInfo.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface IValidatorInfo {\n /// @dev Emitted when the number of max validator is updated\n event MaxValidatorNumberUpdated(uint256);\n /// @dev Emitted when the number of reserved slots for prioritized validators is updated\n event MaxPrioritizedValidatorNumberUpdated(uint256);\n\n /**\n * @dev Returns the maximum number of validators in the epoch\n */\n function maxValidatorNumber() external view returns (uint256 _maximumValidatorNumber);\n\n /**\n * @dev Returns the number of reserved slots for prioritized validators\n */\n function maxPrioritizedValidatorNumber() external view returns (uint256 _maximumPrioritizedValidatorNumber);\n\n /**\n * @dev Returns the current validator list.\n */\n function getValidators() external view returns (address[] memory);\n\n /**\n * @dev Returns whether the address is either a bridge operator or a block producer.\n */\n function isValidator(address _addr) external view returns (bool);\n\n /**\n * @dev Returns the current block producer list.\n */\n function getBlockProducers() external view returns (address[] memory);\n\n /**\n * @dev Returns whether the address is block producer or not.\n */\n function isBlockProducer(address _addr) external view returns (bool);\n\n /**\n * @dev Returns total numbers of the block producers.\n */\n function totalBlockProducers() external view returns (uint256);\n\n /**\n * @dev Returns the current bridge operator list.\n */\n function getBridgeOperators() external view returns (address[] memory);\n\n /**\n * @dev Returns whether the address is bridge operator or not.\n */\n function isBridgeOperator(address _addr) external view returns (bool);\n\n /**\n * @dev Returns total numbers of the bridge operators.\n */\n function totalBridgeOperators() external view returns (uint256);\n\n /**\n * @dev Updates the max validator number\n *\n * Requirements:\n * - The method caller is admin\n *\n * Emits the event `MaxValidatorNumberUpdated`\n *\n */\n function setMaxValidatorNumber(uint256 _maxValidatorNumber) external;\n\n /**\n * @dev Updates the number of reserved slots for prioritized validators\n *\n * Requirements:\n * - The method caller is admin\n *\n * Emits the event `MaxPrioritizedValidatorNumberUpdated`\n *\n */\n function setMaxPrioritizedValidatorNumber(uint256 _maxPrioritizedValidatorNumber) external;\n}\n" + }, + "contracts/ronin/RoninGatewayV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/access/AccessControlEnumerable.sol\";\nimport \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport \"../extensions/GatewayV2.sol\";\nimport \"../extensions/isolated-governance/IsolatedGovernance.sol\";\nimport \"../extensions/MinimumWithdrawal.sol\";\nimport \"../interfaces/IERC20Mintable.sol\";\nimport \"../interfaces/IERC721Mintable.sol\";\nimport \"../interfaces/IRoninGatewayV2.sol\";\nimport \"../interfaces/validator/IRoninValidatorSet.sol\";\nimport \"../interfaces/IBridgeTracking.sol\";\nimport \"../interfaces/collections/IHasValidatorContract.sol\";\nimport \"../interfaces/collections/IHasBridgeTrackingContract.sol\";\n\ncontract RoninGatewayV2 is\n GatewayV2,\n IsolatedGovernance,\n Initializable,\n MinimumWithdrawal,\n AccessControlEnumerable,\n IRoninGatewayV2,\n IHasValidatorContract,\n IHasBridgeTrackingContract\n{\n using Token for Token.Info;\n using Transfer for Transfer.Request;\n using Transfer for Transfer.Receipt;\n\n /// @dev Withdrawal unlocker role hash\n bytes32 public constant WITHDRAWAL_MIGRATOR = keccak256(\"WITHDRAWAL_MIGRATOR\");\n\n /// @dev Flag indicating whether the withdrawal migrate progress is done\n bool public withdrawalMigrated;\n /// @dev Total withdrawal\n uint256 public withdrawalCount;\n /// @dev Mapping from chain id => deposit id => deposit vote\n mapping(uint256 => mapping(uint256 => IsolatedVote)) public depositVote;\n /// @dev Mapping from withdrawal id => mainchain withdrew vote\n mapping(uint256 => IsolatedVote) public mainchainWithdrewVote;\n /// @dev Mapping from withdrawal id => withdrawal receipt\n mapping(uint256 => Transfer.Receipt) public withdrawal;\n /// @dev Mapping from withdrawal id => validator address => signatures\n mapping(uint256 => mapping(address => bytes)) internal _withdrawalSig;\n /// @dev Mapping from token address => chain id => mainchain token address\n mapping(address => mapping(uint256 => MappedToken)) internal _mainchainToken;\n\n /// @dev The ronin validator contract\n IRoninValidatorSet internal _validatorContract;\n /// @dev The bridge tracking contract\n IBridgeTracking internal _bridgeTrackingContract;\n\n /// @dev Mapping from withdrawal id => vote for recording withdrawal stats\n mapping(uint256 => IsolatedVote) public withdrawalStatVote;\n\n fallback() external payable {\n _fallback();\n }\n\n receive() external payable {\n _fallback();\n }\n\n /**\n * @dev Initializes contract storage.\n */\n function initialize(\n address _roleSetter,\n uint256 _numerator,\n uint256 _denominator,\n address[] calldata _withdrawalMigrators,\n // _packedAddresses[0]: roninTokens\n // _packedAddresses[1]: mainchainTokens\n address[][2] calldata _packedAddresses,\n // _packedNumbers[0]: chainIds\n // _packedNumbers[1]: minimumThresholds\n uint256[][2] calldata _packedNumbers,\n Token.Standard[] calldata _standards\n ) external virtual initializer {\n _setupRole(DEFAULT_ADMIN_ROLE, _roleSetter);\n _setThreshold(_numerator, _denominator);\n if (_packedAddresses[0].length > 0) {\n _mapTokens(_packedAddresses[0], _packedAddresses[1], _packedNumbers[0], _standards);\n _setMinimumThresholds(_packedAddresses[0], _packedNumbers[1]);\n }\n\n for (uint256 _i; _i < _withdrawalMigrators.length; _i++) {\n _grantRole(WITHDRAWAL_MIGRATOR, _withdrawalMigrators[_i]);\n }\n }\n\n /**\n * @inheritdoc IHasValidatorContract\n */\n function validatorContract() external view returns (address) {\n return address(_validatorContract);\n }\n\n /**\n * @inheritdoc IHasValidatorContract\n */\n function setValidatorContract(address _addr) external override onlyAdmin {\n require(_addr.code.length > 0, \"RoninGatewayV2: set to non-contract\");\n _setValidatorContract(_addr);\n }\n\n /**\n * @inheritdoc IHasBridgeTrackingContract\n */\n function bridgeTrackingContract() external view override returns (address) {\n return address(_bridgeTrackingContract);\n }\n\n /**\n * @inheritdoc IHasBridgeTrackingContract\n */\n function setBridgeTrackingContract(address _addr) external override onlyAdmin {\n require(_addr.code.length > 0, \"RoninGatewayV2: set to non-contract\");\n _setBridgeTrackingContract(_addr);\n }\n\n /**\n * @dev Migrates withdrawals.\n *\n * Requirements:\n * - The method caller is the migrator.\n * - The arrays have the same length and its length larger than 0.\n *\n */\n function migrateWithdrawals(Transfer.Request[] calldata _requests, address[] calldata _requesters)\n external\n onlyRole(WITHDRAWAL_MIGRATOR)\n {\n require(!withdrawalMigrated, \"RoninGatewayV2: withdrawals migrated\");\n require(_requesters.length == _requests.length && _requests.length > 0, \"RoninGatewayV2: invalid array lengths\");\n for (uint256 _i; _i < _requests.length; _i++) {\n MappedToken memory _token = getMainchainToken(_requests[_i].tokenAddr, 1);\n require(_requests[_i].info.erc == _token.erc, \"RoninGatewayV2: invalid token standard\");\n _storeAsReceipt(_requests[_i], 1, _requesters[_i], _token.tokenAddr);\n }\n }\n\n /**\n * @dev Mark the migration as done.\n */\n function markWithdrawalMigrated() external {\n require(\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || hasRole(WITHDRAWAL_MIGRATOR, msg.sender),\n \"RoninGatewayV2: unauthorized sender\"\n );\n require(!withdrawalMigrated, \"RoninGatewayV2: withdrawals migrated\");\n withdrawalMigrated = true;\n }\n\n /**\n * @inheritdoc IRoninGatewayV2\n */\n function getWithdrawalSignatures(uint256 _withdrawalId, address[] calldata _validators)\n external\n view\n returns (bytes[] memory _signatures)\n {\n _signatures = new bytes[](_validators.length);\n for (uint256 _i = 0; _i < _validators.length; _i++) {\n _signatures[_i] = _withdrawalSig[_withdrawalId][_validators[_i]];\n }\n }\n\n /**\n * @inheritdoc IRoninGatewayV2\n */\n function depositFor(Transfer.Receipt calldata _receipt) external {\n address _sender = msg.sender;\n uint256 _weight = _getValidatorWeight(_sender);\n _depositFor(_receipt, _sender, _weight, minimumVoteWeight());\n _bridgeTrackingContract.recordVote(IBridgeTracking.VoteKind.Deposit, _receipt.id, _sender);\n }\n\n /**\n * @inheritdoc IRoninGatewayV2\n */\n function tryBulkAcknowledgeMainchainWithdrew(uint256[] calldata _withdrawalIds)\n external\n returns (bool[] memory _executedReceipts)\n {\n address _governor = msg.sender;\n uint256 _weight = _getValidatorWeight(_governor);\n uint256 _minVoteWeight = minimumVoteWeight();\n\n uint256 _withdrawalId;\n _executedReceipts = new bool[](_withdrawalIds.length);\n for (uint256 _i; _i < _withdrawalIds.length; _i++) {\n _withdrawalId = _withdrawalIds[_i];\n _bridgeTrackingContract.recordVote(IBridgeTracking.VoteKind.MainchainWithdrawal, _withdrawalId, _governor);\n if (mainchainWithdrew(_withdrawalId)) {\n _executedReceipts[_i] = true;\n } else {\n IsolatedVote storage _proposal = mainchainWithdrewVote[_withdrawalId];\n Transfer.Receipt memory _withdrawal = withdrawal[_withdrawalId];\n bytes32 _hash = _withdrawal.hash();\n VoteStatus _status = _castVote(_proposal, _governor, _weight, _minVoteWeight, _hash);\n if (_status == VoteStatus.Approved) {\n _bridgeTrackingContract.handleVoteApproved(IBridgeTracking.VoteKind.MainchainWithdrawal, _withdrawalId);\n _proposal.status = VoteStatus.Executed;\n emit MainchainWithdrew(_hash, _withdrawal);\n }\n }\n }\n }\n\n /**\n * @inheritdoc IRoninGatewayV2\n */\n function tryBulkDepositFor(Transfer.Receipt[] calldata _receipts) external returns (bool[] memory _executedReceipts) {\n address _sender = msg.sender;\n uint256 _weight = _getValidatorWeight(_sender);\n\n Transfer.Receipt memory _receipt;\n _executedReceipts = new bool[](_receipts.length);\n uint256 _minVoteWeight = minimumVoteWeight();\n for (uint256 _i; _i < _receipts.length; _i++) {\n _receipt = _receipts[_i];\n _bridgeTrackingContract.recordVote(IBridgeTracking.VoteKind.Deposit, _receipt.id, _sender);\n if (depositVote[_receipt.mainchain.chainId][_receipt.id].status == VoteStatus.Executed) {\n _executedReceipts[_i] = true;\n } else {\n _depositFor(_receipt, _sender, _weight, _minVoteWeight);\n }\n }\n }\n\n /**\n * @inheritdoc IRoninGatewayV2\n */\n function requestWithdrawalFor(Transfer.Request calldata _request, uint256 _chainId) external whenNotPaused {\n _requestWithdrawalFor(_request, msg.sender, _chainId);\n }\n\n /**\n * @inheritdoc IRoninGatewayV2\n */\n function bulkRequestWithdrawalFor(Transfer.Request[] calldata _requests, uint256 _chainId) external whenNotPaused {\n require(_requests.length > 0, \"RoninGatewayV2: empty array\");\n for (uint256 _i; _i < _requests.length; _i++) {\n _requestWithdrawalFor(_requests[_i], msg.sender, _chainId);\n }\n }\n\n /**\n * @inheritdoc IRoninGatewayV2\n */\n function requestWithdrawalSignatures(uint256 _withdrawalId) external whenNotPaused {\n require(!mainchainWithdrew(_withdrawalId), \"RoninGatewayV2: withdrew on mainchain already\");\n Transfer.Receipt memory _receipt = withdrawal[_withdrawalId];\n require(_receipt.ronin.chainId == block.chainid, \"RoninGatewayV2: query for invalid withdrawal\");\n emit WithdrawalSignaturesRequested(_receipt.hash(), _receipt);\n }\n\n /**\n * @inheritdoc IRoninGatewayV2\n */\n function bulkSubmitWithdrawalSignatures(uint256[] calldata _withdrawals, bytes[] calldata _signatures) external {\n address _validator = msg.sender;\n // This checks method caller already\n uint256 _weight = _getValidatorWeight(_validator);\n uint256 _minVoteWeight = minimumVoteWeight();\n\n require(\n _withdrawals.length > 0 && _withdrawals.length == _signatures.length,\n \"RoninGatewayV2: invalid array length\"\n );\n\n uint256 _id;\n for (uint256 _i; _i < _withdrawals.length; _i++) {\n _id = _withdrawals[_i];\n _withdrawalSig[_id][_validator] = _signatures[_i];\n _bridgeTrackingContract.recordVote(IBridgeTracking.VoteKind.Withdrawal, _id, _validator);\n\n IsolatedVote storage _proposal = withdrawalStatVote[_id];\n VoteStatus _status = _castVote(_proposal, _validator, _weight, _minVoteWeight, bytes32(_id));\n if (_status == VoteStatus.Approved) {\n _bridgeTrackingContract.handleVoteApproved(IBridgeTracking.VoteKind.Withdrawal, _id);\n _proposal.status = VoteStatus.Executed;\n }\n }\n }\n\n /**\n * @inheritdoc IRoninGatewayV2\n */\n function mapTokens(\n address[] calldata _roninTokens,\n address[] calldata _mainchainTokens,\n uint256[] calldata _chainIds,\n Token.Standard[] calldata _standards\n ) external onlyAdmin {\n require(_roninTokens.length > 0, \"RoninGatewayV2: invalid array length\");\n _mapTokens(_roninTokens, _mainchainTokens, _chainIds, _standards);\n }\n\n /**\n * @inheritdoc IRoninGatewayV2\n */\n function depositVoted(\n uint256 _chainId,\n uint256 _depositId,\n address _voter\n ) external view returns (bool) {\n return _voted(depositVote[_chainId][_depositId], _voter);\n }\n\n /**\n * @inheritdoc IRoninGatewayV2\n */\n function mainchainWithdrewVoted(uint256 _withdrawalId, address _voter) external view returns (bool) {\n return _voted(mainchainWithdrewVote[_withdrawalId], _voter);\n }\n\n /**\n * @inheritdoc IRoninGatewayV2\n */\n function mainchainWithdrew(uint256 _withdrawalId) public view returns (bool) {\n return mainchainWithdrewVote[_withdrawalId].status == VoteStatus.Executed;\n }\n\n /**\n * @inheritdoc IRoninGatewayV2\n */\n function getMainchainToken(address _roninToken, uint256 _chainId) public view returns (MappedToken memory _token) {\n _token = _mainchainToken[_roninToken][_chainId];\n require(_token.tokenAddr != address(0), \"RoninGatewayV2: unsupported token\");\n }\n\n /**\n * @dev Maps Ronin tokens to mainchain networks.\n *\n * Requirement:\n * - The arrays have the same length.\n *\n * Emits the `TokenMapped` event.\n *\n */\n function _mapTokens(\n address[] calldata _roninTokens,\n address[] calldata _mainchainTokens,\n uint256[] calldata _chainIds,\n Token.Standard[] calldata _standards\n ) internal {\n require(\n _roninTokens.length == _mainchainTokens.length && _roninTokens.length == _chainIds.length,\n \"RoninGatewayV2: invalid array length\"\n );\n\n for (uint256 _i; _i < _roninTokens.length; _i++) {\n _mainchainToken[_roninTokens[_i]][_chainIds[_i]].tokenAddr = _mainchainTokens[_i];\n _mainchainToken[_roninTokens[_i]][_chainIds[_i]].erc = _standards[_i];\n }\n\n emit TokenMapped(_roninTokens, _mainchainTokens, _chainIds, _standards);\n }\n\n /**\n * @dev Deposits based on the receipt.\n *\n * Emits the `Deposited` once the assets are released.\n *\n */\n function _depositFor(\n Transfer.Receipt memory _receipt,\n address _validator,\n uint256 _weight,\n uint256 _minVoteWeight\n ) internal {\n uint256 _id = _receipt.id;\n _receipt.info.validate();\n require(_receipt.kind == Transfer.Kind.Deposit, \"RoninGatewayV2: invalid receipt kind\");\n require(_receipt.ronin.chainId == block.chainid, \"RoninGatewayV2: invalid chain id\");\n MappedToken memory _token = getMainchainToken(_receipt.ronin.tokenAddr, _receipt.mainchain.chainId);\n require(\n _token.erc == _receipt.info.erc && _token.tokenAddr == _receipt.mainchain.tokenAddr,\n \"RoninGatewayV2: invalid receipt\"\n );\n\n IsolatedVote storage _proposal = depositVote[_receipt.mainchain.chainId][_id];\n bytes32 _receiptHash = _receipt.hash();\n VoteStatus _status = _castVote(_proposal, _validator, _weight, _minVoteWeight, _receiptHash);\n if (_status == VoteStatus.Approved) {\n _bridgeTrackingContract.handleVoteApproved(IBridgeTracking.VoteKind.Deposit, _receipt.id);\n _proposal.status = VoteStatus.Executed;\n _receipt.info.handleAssetTransfer(payable(_receipt.ronin.addr), _receipt.ronin.tokenAddr, IWETH(address(0)));\n emit Deposited(_receiptHash, _receipt);\n }\n }\n\n /**\n * @dev Returns the validator weight.\n *\n * Requirements:\n * - The `_addr` weight is larger than 0.\n *\n */\n function _getValidatorWeight(address _addr) internal view returns (uint256 _weight) {\n _weight = _validatorContract.isBridgeOperator(_addr) ? 1 : 0;\n require(_weight > 0, \"RoninGatewayV2: unauthorized sender\");\n }\n\n /**\n * @dev Locks the assets and request withdrawal.\n *\n * Requirements:\n * - The token info is valid.\n *\n * Emits the `WithdrawalRequested` event.\n *\n */\n function _requestWithdrawalFor(\n Transfer.Request calldata _request,\n address _requester,\n uint256 _chainId\n ) internal {\n _request.info.validate();\n _checkWithdrawal(_request);\n MappedToken memory _token = getMainchainToken(_request.tokenAddr, _chainId);\n require(_request.info.erc == _token.erc, \"RoninGatewayV2: invalid token standard\");\n _request.info.transferFrom(_requester, address(this), _request.tokenAddr);\n _storeAsReceipt(_request, _chainId, _requester, _token.tokenAddr);\n }\n\n /**\n * @dev Stores the withdrawal request as a receipt.\n *\n * Emits the `WithdrawalRequested` event.\n *\n */\n function _storeAsReceipt(\n Transfer.Request calldata _request,\n uint256 _chainId,\n address _requester,\n address _mainchainTokenAddr\n ) internal returns (uint256 _withdrawalId) {\n _withdrawalId = withdrawalCount++;\n Transfer.Receipt memory _receipt = _request.into_withdrawal_receipt(\n _requester,\n _withdrawalId,\n _mainchainTokenAddr,\n _chainId\n );\n withdrawal[_withdrawalId] = _receipt;\n emit WithdrawalRequested(_receipt.hash(), _receipt);\n }\n\n /**\n * @dev Don't send me RON.\n */\n function _fallback() internal virtual {\n revert(\"RoninGatewayV2: invalid request\");\n }\n\n /**\n * @inheritdoc GatewayV2\n */\n function _getTotalWeight() internal view virtual override returns (uint256) {\n return _validatorContract.totalBridgeOperators();\n }\n\n /**\n * @dev Sets the validator contract.\n *\n * Emits the event `ValidatorContractUpdated`.\n *\n */\n function _setValidatorContract(address _addr) internal {\n _validatorContract = IRoninValidatorSet(_addr);\n emit ValidatorContractUpdated(_addr);\n }\n\n /**\n * @dev Sets the bridge tracking contract.\n *\n * Emits the event `BridgeTrackingContractUpdated`.\n *\n */\n function _setBridgeTrackingContract(address _addr) internal {\n _bridgeTrackingContract = IBridgeTracking(_addr);\n emit BridgeTrackingContractUpdated(_addr);\n }\n}\n" + }, + "@openzeppelin/contracts/access/AccessControlEnumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerable.sol\";\nimport \"./AccessControl.sol\";\nimport \"../utils/structs/EnumerableSet.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n}\n" + }, + "contracts/extensions/GatewayV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/security/Pausable.sol\";\nimport \"../interfaces/IQuorum.sol\";\nimport \"./collections/HasProxyAdmin.sol\";\n\nabstract contract GatewayV2 is HasProxyAdmin, Pausable, IQuorum {\n uint256 internal _num;\n uint256 internal _denom;\n\n address private ______deprecated;\n uint256 public nonce;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n /**\n * @inheritdoc IQuorum\n */\n function getThreshold() external view virtual returns (uint256, uint256) {\n return (_num, _denom);\n }\n\n /**\n * @inheritdoc IQuorum\n */\n function checkThreshold(uint256 _voteWeight) external view virtual returns (bool) {\n return _voteWeight * _denom >= _num * _getTotalWeight();\n }\n\n /**\n * @inheritdoc IQuorum\n */\n function setThreshold(uint256 _numerator, uint256 _denominator)\n external\n virtual\n onlyAdmin\n returns (uint256, uint256)\n {\n return _setThreshold(_numerator, _denominator);\n }\n\n /**\n * @dev Triggers paused state.\n */\n function pause() external onlyAdmin {\n _pause();\n }\n\n /**\n * @dev Triggers unpaused state.\n */\n function unpause() external onlyAdmin {\n _unpause();\n }\n\n /**\n * @inheritdoc IQuorum\n */\n function minimumVoteWeight() public view virtual returns (uint256) {\n return _minimumVoteWeight(_getTotalWeight());\n }\n\n /**\n * @dev Sets threshold and returns the old one.\n *\n * Emits the `ThresholdUpdated` event.\n *\n */\n function _setThreshold(uint256 _numerator, uint256 _denominator)\n internal\n virtual\n returns (uint256 _previousNum, uint256 _previousDenom)\n {\n require(_numerator <= _denominator, \"GatewayV2: invalid threshold\");\n _previousNum = _num;\n _previousDenom = _denom;\n _num = _numerator;\n _denom = _denominator;\n emit ThresholdUpdated(nonce++, _numerator, _denominator, _previousNum, _previousDenom);\n }\n\n /**\n * @dev Returns minimum vote weight.\n */\n function _minimumVoteWeight(uint256 _totalWeight) internal view virtual returns (uint256) {\n return (_num * _totalWeight + _denom - 1) / _denom;\n }\n\n /**\n * @dev Returns the total weight.\n */\n function _getTotalWeight() internal view virtual returns (uint256);\n}\n" + }, + "contracts/extensions/isolated-governance/IsolatedGovernance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"../../interfaces/consumers/VoteStatusConsumer.sol\";\n\nabstract contract IsolatedGovernance is VoteStatusConsumer {\n struct IsolatedVote {\n VoteStatus status;\n bytes32 finalHash;\n /// @dev Mapping from voter => receipt hash\n mapping(address => bytes32) voteHashOf;\n /// @dev Mapping from receipt hash => vote weight\n mapping(bytes32 => uint256) weight;\n }\n\n /**\n * @dev Casts vote for the receipt with the receipt hash `_hash`.\n *\n * Requirements:\n * - The vote is not finalized.\n * - The voter has not voted for the round.\n *\n */\n function _castVote(\n IsolatedVote storage _proposal,\n address _voter,\n uint256 _voterWeight,\n uint256 _minimumVoteWeight,\n bytes32 _hash\n ) internal virtual returns (VoteStatus _status) {\n if (_voted(_proposal, _voter)) {\n revert(\n string(abi.encodePacked(\"IsolatedGovernance: \", Strings.toHexString(uint160(_voter), 20), \" already voted\"))\n );\n }\n\n // Record for voter\n _proposal.voteHashOf[_voter] = _hash;\n // Increase vote weight\n uint256 _weight = _proposal.weight[_hash] += _voterWeight;\n\n if (_weight >= _minimumVoteWeight && _proposal.status == VoteStatus.Pending) {\n _proposal.status = VoteStatus.Approved;\n _proposal.finalHash = _hash;\n }\n\n _status = _proposal.status;\n }\n\n /**\n * @dev Returns whether the voter casted for the proposal.\n */\n function _voted(IsolatedVote storage _proposal, address _voter) internal view virtual returns (bool) {\n return _proposal.voteHashOf[_voter] != bytes32(0);\n }\n}\n" + }, + "contracts/extensions/MinimumWithdrawal.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./collections/HasProxyAdmin.sol\";\nimport \"../libraries/Transfer.sol\";\n\nabstract contract MinimumWithdrawal is HasProxyAdmin {\n /// @dev Emitted when the minimum thresholds are updated\n event MinimumThresholdsUpdated(address[] tokens, uint256[] threshold);\n\n /// @dev Mapping from token address => minimum thresholds\n mapping(address => uint256) public minimumThreshold;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n /**\n * @dev Sets the minimum thresholds to withdraw.\n *\n * Requirements:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `MinimumThresholdsUpdated` event.\n *\n */\n function setMinimumThresholds(address[] calldata _tokens, uint256[] calldata _thresholds) external virtual onlyAdmin {\n require(_tokens.length > 0, \"MinimumWithdrawal: invalid array length\");\n _setMinimumThresholds(_tokens, _thresholds);\n }\n\n /**\n * @dev Sets minimum thresholds.\n *\n * Requirements:\n * - The array lengths are equal.\n *\n * Emits the `MinimumThresholdsUpdated` event.\n *\n */\n function _setMinimumThresholds(address[] calldata _tokens, uint256[] calldata _thresholds) internal virtual {\n require(_tokens.length == _thresholds.length, \"MinimumWithdrawal: invalid array length\");\n for (uint256 _i; _i < _tokens.length; _i++) {\n minimumThreshold[_tokens[_i]] = _thresholds[_i];\n }\n emit MinimumThresholdsUpdated(_tokens, _thresholds);\n }\n\n /**\n * @dev Checks whether the request is larger than or equal to the minimum threshold.\n */\n function _checkWithdrawal(Transfer.Request calldata _request) internal view {\n require(\n _request.info.erc != Token.Standard.ERC20 || _request.info.quantity >= minimumThreshold[_request.tokenAddr],\n \"MinimumWithdrawal: query for too small quantity\"\n );\n }\n}\n" + }, + "contracts/interfaces/IERC20Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.2;\n\ninterface IERC20Mintable {\n function mint(address _to, uint256 _value) external returns (bool _success);\n}\n" + }, + "contracts/interfaces/IERC721Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IERC721Mintable {\n function mint(address _to, uint256 _tokenId) external returns (bool);\n}\n" + }, + "contracts/interfaces/IRoninGatewayV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../libraries/Transfer.sol\";\nimport \"./consumers/MappedTokenConsumer.sol\";\n\ninterface IRoninGatewayV2 is MappedTokenConsumer {\n /// @dev Emitted when the assets are depositted\n event Deposited(bytes32 receiptHash, Transfer.Receipt receipt);\n /// @dev Emitted when the withdrawal is requested\n event WithdrawalRequested(bytes32 receiptHash, Transfer.Receipt);\n /// @dev Emitted when the assets are withdrawn on mainchain\n event MainchainWithdrew(bytes32 receiptHash, Transfer.Receipt receipt);\n /// @dev Emitted when the withdrawal signatures is requested\n event WithdrawalSignaturesRequested(bytes32 receiptHash, Transfer.Receipt);\n /// @dev Emitted when the tokens are mapped\n event TokenMapped(address[] roninTokens, address[] mainchainTokens, uint256[] chainIds, Token.Standard[] standards);\n\n /**\n * @dev Returns withdrawal count.\n */\n function withdrawalCount() external view returns (uint256);\n\n /**\n * @dev Returns withdrawal signatures.\n */\n function getWithdrawalSignatures(uint256 _withdrawalId, address[] calldata _validators)\n external\n view\n returns (bytes[] memory);\n\n /**\n * @dev Deposits based on the receipt.\n *\n * Requirements:\n * - The method caller is a validator.\n *\n * Emits the `Deposited` once the assets are released.\n *\n * @notice The assets will be transferred whenever the valid call passes the quorum threshold.\n *\n */\n function depositFor(Transfer.Receipt calldata _receipt) external;\n\n /**\n * @dev Marks the withdrawals are done on mainchain and returns the boolean array indicating whether the withdrawal\n * vote is already done before.\n *\n * Requirements:\n * - The method caller is a validator.\n *\n * Emits the `MainchainWithdrew` once the valid call passes the quorum threshold.\n *\n * @notice Not reverting to avoid unnecessary failed transactions because the validators can send transactions at the\n * same time.\n *\n */\n function tryBulkAcknowledgeMainchainWithdrew(uint256[] calldata _withdrawalIds) external returns (bool[] memory);\n\n /**\n * @dev Tries bulk deposits based on the receipts and returns the boolean array indicating whether the deposit vote\n * is already done before. Reverts if the deposit is invalid or is voted by the validator again.\n *\n * Requirements:\n * - The method caller is a validator.\n *\n * Emits the `Deposited` once the assets are released.\n *\n * @notice The assets will be transferred whenever the valid call for the receipt passes the quorum threshold. Not\n * reverting to avoid unnecessary failed transactions because the validators can send transactions at the same time.\n *\n */\n function tryBulkDepositFor(Transfer.Receipt[] calldata _receipts) external returns (bool[] memory);\n\n /**\n * @dev Locks the assets and request withdrawal.\n *\n * Emits the `WithdrawalRequested` event.\n *\n */\n function requestWithdrawalFor(Transfer.Request calldata _request, uint256 _chainId) external;\n\n /**\n * @dev Bulk requests withdrawals.\n *\n * Emits the `WithdrawalRequested` events.\n *\n */\n function bulkRequestWithdrawalFor(Transfer.Request[] calldata _requests, uint256 _chainId) external;\n\n /**\n * @dev Requests withdrawal signatures for a specific withdrawal.\n *\n * Emits the `WithdrawalSignaturesRequested` event.\n *\n */\n function requestWithdrawalSignatures(uint256 _withdrawalId) external;\n\n /**\n * @dev Submits withdrawal signatures.\n *\n * Requirements:\n * - The method caller is a validator.\n *\n */\n function bulkSubmitWithdrawalSignatures(uint256[] calldata _withdrawals, bytes[] calldata _signatures) external;\n\n /**\n * @dev Maps Ronin tokens to mainchain networks.\n *\n * Requirement:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `TokenMapped` event.\n *\n */\n function mapTokens(\n address[] calldata _roninTokens,\n address[] calldata _mainchainTokens,\n uint256[] calldata chainIds,\n Token.Standard[] calldata _standards\n ) external;\n\n /**\n * @dev Returns whether the deposit is casted by the voter.\n */\n function depositVoted(\n uint256 _chainId,\n uint256 _depositId,\n address _voter\n ) external view returns (bool);\n\n /**\n * @dev Returns whether the mainchain withdrew is casted by the voter.\n */\n function mainchainWithdrewVoted(uint256 _withdrawalId, address _voter) external view returns (bool);\n\n /**\n * @dev Returns whether the withdrawal is done on mainchain.\n */\n function mainchainWithdrew(uint256 _withdrawalId) external view returns (bool);\n\n /**\n * @dev Returns mainchain token address.\n * Reverts for unsupported token.\n */\n function getMainchainToken(address _roninToken, uint256 _chainId) external view returns (MappedToken memory _token);\n}\n" + }, + "contracts/interfaces/collections/IHasBridgeTrackingContract.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface IHasBridgeTrackingContract {\n /// @dev Emitted when the bridge tracking contract is updated.\n event BridgeTrackingContractUpdated(address);\n\n /**\n * @dev Returns the bridge tracking contract.\n */\n function bridgeTrackingContract() external view returns (address);\n\n /**\n * @dev Sets the bridge tracking contract.\n *\n * Requirements:\n * - The method caller is admin.\n * - The new address is a contract.\n *\n * Emits the event `BridgeTrackingContractUpdated`.\n *\n */\n function setBridgeTrackingContract(address) external;\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControlEnumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerable is IAccessControl {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(uint160(account), 20),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/security/Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor() {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n" + }, + "contracts/interfaces/IQuorum.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IQuorum {\n /// @dev Emitted when the threshold is updated\n event ThresholdUpdated(\n uint256 indexed nonce,\n uint256 indexed numerator,\n uint256 indexed denominator,\n uint256 previousNumerator,\n uint256 previousDenominator\n );\n\n /**\n * @dev Returns the threshold.\n */\n function getThreshold() external view returns (uint256 _num, uint256 _denom);\n\n /**\n * @dev Checks whether the `_voteWeight` passes the threshold.\n */\n function checkThreshold(uint256 _voteWeight) external view returns (bool);\n\n /**\n * @dev Returns the minimum vote weight to pass the threshold.\n */\n function minimumVoteWeight() external view returns (uint256);\n\n /**\n * @dev Sets the threshold.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the `ThresholdUpdated` event.\n *\n */\n function setThreshold(uint256 _numerator, uint256 _denominator)\n external\n returns (uint256 _previousNum, uint256 _previousDenom);\n}\n" + }, + "contracts/interfaces/consumers/VoteStatusConsumer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface VoteStatusConsumer {\n enum VoteStatus {\n Pending,\n Approved,\n Executed,\n Rejected\n }\n}\n" + }, + "contracts/libraries/Transfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"./Token.sol\";\n\nlibrary Transfer {\n using ECDSA for bytes32;\n\n enum Kind {\n Deposit,\n Withdrawal\n }\n\n struct Request {\n // For deposit request: Recipient address on Ronin network\n // For withdrawal request: Recipient address on mainchain network\n address recipientAddr;\n // Token address to deposit/withdraw\n // Value 0: native token\n address tokenAddr;\n Token.Info info;\n }\n\n /**\n * @dev Converts the transfer request into the deposit receipt.\n */\n function into_deposit_receipt(\n Request memory _request,\n address _requester,\n uint256 _id,\n address _roninTokenAddr,\n uint256 _roninChainId\n ) internal view returns (Receipt memory _receipt) {\n _receipt.id = _id;\n _receipt.kind = Kind.Deposit;\n _receipt.mainchain.addr = _requester;\n _receipt.mainchain.tokenAddr = _request.tokenAddr;\n _receipt.mainchain.chainId = block.chainid;\n _receipt.ronin.addr = _request.recipientAddr;\n _receipt.ronin.tokenAddr = _roninTokenAddr;\n _receipt.ronin.chainId = _roninChainId;\n _receipt.info = _request.info;\n }\n\n /**\n * @dev Converts the transfer request into the withdrawal receipt.\n */\n function into_withdrawal_receipt(\n Request memory _request,\n address _requester,\n uint256 _id,\n address _mainchainTokenAddr,\n uint256 _mainchainId\n ) internal view returns (Receipt memory _receipt) {\n _receipt.id = _id;\n _receipt.kind = Kind.Withdrawal;\n _receipt.ronin.addr = _requester;\n _receipt.ronin.tokenAddr = _request.tokenAddr;\n _receipt.ronin.chainId = block.chainid;\n _receipt.mainchain.addr = _request.recipientAddr;\n _receipt.mainchain.tokenAddr = _mainchainTokenAddr;\n _receipt.mainchain.chainId = _mainchainId;\n _receipt.info = _request.info;\n }\n\n struct Receipt {\n uint256 id;\n Kind kind;\n Token.Owner mainchain;\n Token.Owner ronin;\n Token.Info info;\n }\n\n // keccak256(\"Receipt(uint256 id,uint8 kind,TokenOwner mainchain,TokenOwner ronin,TokenInfo info)TokenInfo(uint8 erc,uint256 id,uint256 quantity)TokenOwner(address addr,address tokenAddr,uint256 chainId)\");\n bytes32 public constant TYPE_HASH = 0xb9d1fe7c9deeec5dc90a2f47ff1684239519f2545b2228d3d91fb27df3189eea;\n\n /**\n * @dev Returns token info struct hash.\n */\n function hash(Receipt memory _receipt) internal pure returns (bytes32) {\n return\n keccak256(\n abi.encode(\n TYPE_HASH,\n _receipt.id,\n _receipt.kind,\n Token.hash(_receipt.mainchain),\n Token.hash(_receipt.ronin),\n Token.hash(_receipt.info)\n )\n );\n }\n\n /**\n * @dev Returns the receipt digest.\n */\n function receiptDigest(bytes32 _domainSeparator, bytes32 _receiptHash) internal pure returns (bytes32) {\n return _domainSeparator.toTypedDataHash(_receiptHash);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "contracts/libraries/Token.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"../interfaces/IWETH.sol\";\n\nlibrary Token {\n enum Standard {\n ERC20,\n ERC721\n }\n struct Info {\n Standard erc;\n // For ERC20: the id must be 0 and the quantity is larger than 0.\n // For ERC721: the quantity must be 0.\n uint256 id;\n uint256 quantity;\n }\n\n // keccak256(\"TokenInfo(uint8 erc,uint256 id,uint256 quantity)\");\n bytes32 public constant INFO_TYPE_HASH = 0x1e2b74b2a792d5c0f0b6e59b037fa9d43d84fbb759337f0112fcc15ca414fc8d;\n\n /**\n * @dev Returns token info struct hash.\n */\n function hash(Info memory _info) internal pure returns (bytes32) {\n return keccak256(abi.encode(INFO_TYPE_HASH, _info.erc, _info.id, _info.quantity));\n }\n\n /**\n * @dev Validates the token info.\n */\n function validate(Info memory _info) internal pure {\n require(\n (_info.erc == Standard.ERC20 && _info.quantity > 0 && _info.id == 0) ||\n (_info.erc == Standard.ERC721 && _info.quantity == 0),\n \"Token: invalid info\"\n );\n }\n\n /**\n * @dev Transfer asset from.\n *\n * Requirements:\n * - The `_from` address must approve for the contract using this library.\n *\n */\n function transferFrom(\n Info memory _info,\n address _from,\n address _to,\n address _token\n ) internal {\n bool _success;\n bytes memory _data;\n if (_info.erc == Standard.ERC20) {\n (_success, _data) = _token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, _from, _to, _info.quantity));\n _success = _success && (_data.length == 0 || abi.decode(_data, (bool)));\n } else if (_info.erc == Standard.ERC721) {\n // bytes4(keccak256(\"transferFrom(address,address,uint256)\"))\n (_success, ) = _token.call(abi.encodeWithSelector(0x23b872dd, _from, _to, _info.id));\n } else {\n revert(\"Token: unsupported token standard\");\n }\n\n if (!_success) {\n revert(\n string(\n abi.encodePacked(\n \"Token: could not transfer \",\n toString(_info),\n \" from \",\n Strings.toHexString(uint160(_from), 20),\n \" to \",\n Strings.toHexString(uint160(_to), 20),\n \" token \",\n Strings.toHexString(uint160(_token), 20)\n )\n )\n );\n }\n }\n\n /**\n * @dev Transfers ERC721 token and returns the result.\n */\n function tryTransferERC721(\n address _token,\n address _to,\n uint256 _id\n ) internal returns (bool _success) {\n (_success, ) = _token.call(abi.encodeWithSelector(IERC721.transferFrom.selector, address(this), _to, _id));\n }\n\n /**\n * @dev Transfers ERC20 token and returns the result.\n */\n function tryTransferERC20(\n address _token,\n address _to,\n uint256 _quantity\n ) internal returns (bool _success) {\n bytes memory _data;\n (_success, _data) = _token.call(abi.encodeWithSelector(IERC20.transfer.selector, _to, _quantity));\n _success = _success && (_data.length == 0 || abi.decode(_data, (bool)));\n }\n\n /**\n * @dev Transfer assets from current address to `_to` address.\n */\n function transfer(\n Info memory _info,\n address _to,\n address _token\n ) internal {\n bool _success;\n if (_info.erc == Standard.ERC20) {\n _success = tryTransferERC20(_token, _to, _info.quantity);\n } else if (_info.erc == Standard.ERC721) {\n _success = tryTransferERC721(_token, _to, _info.id);\n } else {\n revert(\"Token: unsupported token standard\");\n }\n\n if (!_success) {\n revert(\n string(\n abi.encodePacked(\n \"Token: could not transfer \",\n toString(_info),\n \" to \",\n Strings.toHexString(uint160(_to), 20),\n \" token \",\n Strings.toHexString(uint160(_token), 20)\n )\n )\n );\n }\n }\n\n /**\n * @dev Tries minting and transfering assets.\n *\n * @notice Prioritizes transfer native token if the token is wrapped.\n *\n */\n function handleAssetTransfer(\n Info memory _info,\n address payable _to,\n address _token,\n IWETH _wrappedNativeToken\n ) internal {\n bool _success;\n if (_token == address(_wrappedNativeToken)) {\n // Try sending the native token before transferring the wrapped token\n if (!_to.send(_info.quantity)) {\n _wrappedNativeToken.deposit{ value: _info.quantity }();\n transfer(_info, _to, _token);\n }\n } else if (_info.erc == Token.Standard.ERC20) {\n uint256 _balance = IERC20(_token).balanceOf(address(this));\n\n if (_balance < _info.quantity) {\n // bytes4(keccak256(\"mint(address,uint256)\"))\n (_success, ) = _token.call(abi.encodeWithSelector(0x40c10f19, address(this), _info.quantity - _balance));\n require(_success, \"Token: ERC20 minting failed\");\n }\n\n transfer(_info, _to, _token);\n } else if (_info.erc == Token.Standard.ERC721) {\n if (!tryTransferERC721(_token, _to, _info.id)) {\n // bytes4(keccak256(\"mint(address,uint256)\"))\n (_success, ) = _token.call(abi.encodeWithSelector(0x40c10f19, _to, _info.id));\n require(_success, \"Token: ERC721 minting failed\");\n }\n } else {\n revert(\"Token: unsupported token standard\");\n }\n }\n\n /**\n * @dev Returns readable string.\n */\n function toString(Info memory _info) internal pure returns (string memory) {\n return\n string(\n abi.encodePacked(\n \"TokenInfo(\",\n Strings.toHexString(uint160(_info.erc), 1),\n \",\",\n Strings.toHexString(_info.id),\n \",\",\n Strings.toHexString(_info.quantity),\n \")\"\n )\n );\n }\n\n struct Owner {\n address addr;\n address tokenAddr;\n uint256 chainId;\n }\n\n // keccak256(\"TokenOwner(address addr,address tokenAddr,uint256 chainId)\");\n bytes32 public constant OWNER_TYPE_HASH = 0x353bdd8d69b9e3185b3972e08b03845c0c14a21a390215302776a7a34b0e8764;\n\n /**\n * @dev Returns ownership struct hash.\n */\n function hash(Owner memory _owner) internal pure returns (bytes32) {\n return keccak256(abi.encode(OWNER_TYPE_HASH, _owner.addr, _owner.tokenAddr, _owner.chainId));\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IWETH.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IWETH {\n function deposit() external payable;\n\n function withdraw(uint256 _wad) external;\n\n function balanceOf(address) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/consumers/MappedTokenConsumer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../../libraries/Token.sol\";\n\ninterface MappedTokenConsumer {\n struct MappedToken {\n Token.Standard erc;\n address tokenAddr;\n }\n}\n" + }, + "contracts/extensions/collections/HasBridgeTrackingContract.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./HasProxyAdmin.sol\";\nimport \"../../interfaces/collections/IHasBridgeTrackingContract.sol\";\nimport \"../../interfaces/IBridgeTracking.sol\";\n\ncontract HasBridgeTrackingContract is IHasBridgeTrackingContract, HasProxyAdmin {\n IBridgeTracking internal _bridgeTrackingContract;\n\n modifier onlyBridgeTrackingContract() {\n require(\n bridgeTrackingContract() == msg.sender,\n \"HasBridgeTrackingContract: method caller must be bridge tracking contract\"\n );\n _;\n }\n\n /**\n * @inheritdoc IHasBridgeTrackingContract\n */\n function bridgeTrackingContract() public view override returns (address) {\n return address(_bridgeTrackingContract);\n }\n\n /**\n * @inheritdoc IHasBridgeTrackingContract\n */\n function setBridgeTrackingContract(address _addr) external virtual override onlyAdmin {\n require(_addr.code.length > 0, \"HasBridgeTrackingContract: set to non-contract\");\n _setBridgeTrackingContract(_addr);\n }\n\n /**\n * @dev Sets the bridge tracking contract.\n *\n * Emits the event `BridgeTrackingContractUpdated`.\n *\n */\n function _setBridgeTrackingContract(address _addr) internal {\n _bridgeTrackingContract = IBridgeTracking(_addr);\n emit BridgeTrackingContractUpdated(_addr);\n }\n}\n" + }, + "contracts/ronin/validator/CoinbaseExecution.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../extensions/collections/HasBridgeTrackingContract.sol\";\nimport \"../../extensions/collections/HasMaintenanceContract.sol\";\nimport \"../../extensions/collections/HasSlashIndicatorContract.sol\";\nimport \"../../extensions/collections/HasStakingVestingContract.sol\";\nimport \"../../extensions/RONTransferHelper.sol\";\nimport \"../../interfaces/validator/ICoinbaseExecution.sol\";\nimport \"../../libraries/EnumFlags.sol\";\nimport \"../../libraries/Math.sol\";\nimport \"../../precompile-usages/PrecompileUsageSortValidators.sol\";\nimport \"../../precompile-usages/PrecompileUsagePickValidatorSet.sol\";\nimport \"./storage-fragments/CommonStorage.sol\";\nimport \"./CandidateManager.sol\";\n\nabstract contract CoinbaseExecution is\n ICoinbaseExecution,\n RONTransferHelper,\n PrecompileUsageSortValidators,\n PrecompileUsagePickValidatorSet,\n HasStakingVestingContract,\n HasBridgeTrackingContract,\n HasMaintenanceContract,\n HasSlashIndicatorContract,\n CandidateManager,\n CommonStorage\n{\n using EnumFlags for EnumFlags.ValidatorFlag;\n\n modifier onlyCoinbase() {\n require(msg.sender == block.coinbase, \"RoninValidatorSet: method caller must be coinbase\");\n _;\n }\n\n modifier whenEpochEnding() {\n require(epochEndingAt(block.number), \"RoninValidatorSet: only allowed at the end of epoch\");\n _;\n }\n\n modifier oncePerEpoch() {\n require(\n epochOf(_lastUpdatedBlock) < epochOf(block.number),\n \"RoninValidatorSet: query for already wrapped up epoch\"\n );\n _lastUpdatedBlock = block.number;\n _;\n }\n\n /**\n * @inheritdoc ICoinbaseExecution\n */\n function submitBlockReward() external payable override onlyCoinbase {\n uint256 _submittedReward = msg.value;\n address _coinbaseAddr = msg.sender;\n bool _requestForBlockProducer = isBlockProducer(_coinbaseAddr) &&\n !_jailed(_coinbaseAddr) &&\n !_miningRewardDeprecated(_coinbaseAddr, currentPeriod());\n bool _requestForBridgeOperator = true;\n\n (, uint256 _blockProducerBonus, uint256 _bridgeOperatorBonus) = _stakingVestingContract.requestBonus(\n _requestForBlockProducer,\n _requestForBridgeOperator\n );\n\n _totalBridgeReward += _bridgeOperatorBonus;\n\n // Deprecates reward for non-validator or slashed validator\n if (!_requestForBlockProducer) {\n _totalDeprecatedReward += _submittedReward;\n emit BlockRewardDeprecated(_coinbaseAddr, _submittedReward, BlockRewardDeprecatedType.UNAVAILABILITY);\n return;\n }\n\n emit BlockRewardSubmitted(_coinbaseAddr, _submittedReward, _blockProducerBonus);\n\n uint256 _period = currentPeriod();\n uint256 _reward = _submittedReward + _blockProducerBonus;\n uint256 _cutOffReward;\n if (_miningRewardBailoutCutOffAtPeriod[_coinbaseAddr][_period]) {\n (, , , uint256 _cutOffPercentage) = _slashIndicatorContract.getCreditScoreConfigs();\n _cutOffReward = (_reward * _cutOffPercentage) / _MAX_PERCENTAGE;\n _totalDeprecatedReward += _cutOffReward;\n emit BlockRewardDeprecated(_coinbaseAddr, _cutOffReward, BlockRewardDeprecatedType.AFTER_BAILOUT);\n }\n\n _reward -= _cutOffReward;\n uint256 _rate = _candidateInfo[_coinbaseAddr].commissionRate;\n uint256 _miningAmount = (_rate * _reward) / _MAX_PERCENTAGE;\n _miningReward[_coinbaseAddr] += _miningAmount;\n\n uint256 _delegatingAmount = _reward - _miningAmount;\n _delegatingReward[_coinbaseAddr] += _delegatingAmount;\n }\n\n /**\n * @inheritdoc ICoinbaseExecution\n */\n function wrapUpEpoch() external payable virtual override onlyCoinbase whenEpochEnding oncePerEpoch {\n uint256 _newPeriod = _computePeriod(block.timestamp);\n bool _periodEnding = _isPeriodEnding(_newPeriod);\n _currentPeriodStartAtBlock = block.number + 1;\n\n address[] memory _currentValidators = getValidators();\n uint256 _epoch = epochOf(block.number);\n uint256 _lastPeriod = currentPeriod();\n\n if (_periodEnding) {\n _syncBridgeOperatingReward(_lastPeriod, _currentValidators);\n (\n uint256 _totalDelegatingReward,\n uint256[] memory _delegatingRewards\n ) = _distributeRewardToTreasuriesAndCalculateTotalDelegatingReward(_lastPeriod, _currentValidators);\n _settleAndTransferDelegatingRewards(_lastPeriod, _currentValidators, _totalDelegatingReward, _delegatingRewards);\n _recycleDeprecatedRewards();\n _slashIndicatorContract.updateCreditScores(_currentValidators, _lastPeriod);\n _currentValidators = _syncValidatorSet(_newPeriod);\n }\n _revampBlockProducers(_newPeriod, _currentValidators);\n emit WrappedUpEpoch(_lastPeriod, _epoch, _periodEnding);\n _periodOf[_epoch + 1] = _newPeriod;\n _lastUpdatedPeriod = _newPeriod;\n }\n\n /**\n * @dev This loop over the all current validators to sync the bridge operating reward.\n *\n * Note: This method should be called once in the end of each period.\n *\n */\n function _syncBridgeOperatingReward(uint256 _lastPeriod, address[] memory _currentValidators) internal {\n IBridgeTracking _bridgeTracking = _bridgeTrackingContract;\n uint256 _totalBridgeBallots = _bridgeTracking.totalBallots(_lastPeriod);\n uint256 _totalBridgeVotes = _bridgeTracking.totalVotes(_lastPeriod);\n uint256[] memory _bridgeBallots = _bridgeTracking.getManyTotalBallots(_lastPeriod, _currentValidators);\n (\n uint256 _missingVotesRatioTier1,\n uint256 _missingVotesRatioTier2,\n uint256 _jailDurationForMissingVotesRatioTier2,\n uint256 _skipBridgeOperatorSlashingThreshold\n ) = _slashIndicatorContract.getBridgeOperatorSlashingConfigs();\n for (uint _i = 0; _i < _currentValidators.length; _i++) {\n _updateValidatorRewardBaseOnBridgeOperatingPerformance(\n _lastPeriod,\n _currentValidators[_i],\n _bridgeBallots[_i],\n _totalBridgeVotes,\n _totalBridgeBallots,\n _missingVotesRatioTier1,\n _missingVotesRatioTier2,\n _jailDurationForMissingVotesRatioTier2,\n _skipBridgeOperatorSlashingThreshold\n );\n }\n }\n\n /**\n * @dev Updates validator reward based on the corresponding bridge operator performance.\n */\n function _updateValidatorRewardBaseOnBridgeOperatingPerformance(\n uint256 _period,\n address _validator,\n uint256 _validatorBallots,\n uint256 _totalVotes,\n uint256 _totalBallots,\n uint256 _ratioTier1,\n uint256 _ratioTier2,\n uint256 _jailDurationTier2,\n uint256 _skipBridgeOperatorSlashingThreshold\n ) internal {\n // Shares equally in case the bridge has nothing to votes\n bool _emptyBallot = _totalBallots == 0;\n if (_emptyBallot && _totalVotes == 0) {\n _bridgeOperatingReward[_validator] = _totalBridgeReward / totalBridgeOperators();\n return;\n } else if (_emptyBallot) {\n return;\n }\n\n // Skips slashing in case the total number of votes is too small\n if (_totalVotes <= _skipBridgeOperatorSlashingThreshold) {\n _bridgeOperatingReward[_validator] = (_totalBridgeReward * _validatorBallots) / _totalBallots;\n return;\n }\n\n uint256 _votedRatio = (_validatorBallots * _MAX_PERCENTAGE) / _totalVotes;\n uint256 _missedRatio = _MAX_PERCENTAGE - _votedRatio;\n if (_missedRatio > _ratioTier2) {\n _bridgeRewardDeprecatedAtPeriod[_validator][_period] = true;\n _miningRewardDeprecatedAtPeriod[_validator][_period] = true;\n _jailedUntil[_validator] = Math.max(block.number + _jailDurationTier2, _jailedUntil[_validator]);\n emit ValidatorPunished(_validator, _period, _jailedUntil[_validator], 0, true, true);\n } else if (_missedRatio > _ratioTier1) {\n _bridgeRewardDeprecatedAtPeriod[_validator][_period] = true;\n emit ValidatorPunished(_validator, _period, _jailedUntil[_validator], 0, false, true);\n } else if (_totalBallots > 0) {\n _bridgeOperatingReward[_validator] = (_totalBridgeReward * _validatorBallots) / _totalBallots;\n }\n }\n\n /**\n * @dev This loops over all current validators to:\n * - Update delegating reward for and calculate total delegating rewards to be sent to the staking contract,\n * - Distribute the reward of block producers and bridge operators to their treasury addresses,\n * - Update the total deprecated reward if the two previous conditions do not sastify.\n *\n * Note: This method should be called once in the end of each period.\n *\n */\n function _distributeRewardToTreasuriesAndCalculateTotalDelegatingReward(\n uint256 _lastPeriod,\n address[] memory _currentValidators\n ) private returns (uint256 _totalDelegatingReward, uint256[] memory _delegatingRewards) {\n address _consensusAddr;\n address payable _treasury;\n _delegatingRewards = new uint256[](_currentValidators.length);\n for (uint _i = 0; _i < _currentValidators.length; _i++) {\n _consensusAddr = _currentValidators[_i];\n _treasury = _candidateInfo[_consensusAddr].treasuryAddr;\n\n if (!_bridgeRewardDeprecated(_consensusAddr, _lastPeriod)) {\n _distributeBridgeOperatingReward(_consensusAddr, _candidateInfo[_consensusAddr].bridgeOperatorAddr, _treasury);\n } else {\n _totalDeprecatedReward += _bridgeOperatingReward[_consensusAddr];\n }\n\n if (!_jailed(_consensusAddr) && !_miningRewardDeprecated(_consensusAddr, _lastPeriod)) {\n _totalDelegatingReward += _delegatingReward[_consensusAddr];\n _delegatingRewards[_i] = _delegatingReward[_consensusAddr];\n _distributeMiningReward(_consensusAddr, _treasury);\n } else {\n _totalDeprecatedReward += _miningReward[_consensusAddr] + _delegatingReward[_consensusAddr];\n }\n\n delete _delegatingReward[_consensusAddr];\n delete _miningReward[_consensusAddr];\n delete _bridgeOperatingReward[_consensusAddr];\n }\n delete _totalBridgeReward;\n }\n\n /**\n * @dev Distributes bonus of staking vesting and mining fee for the block producer.\n *\n * Emits the `MiningRewardDistributed` once the reward is distributed successfully.\n * Emits the `MiningRewardDistributionFailed` once the contract fails to distribute reward.\n *\n * Note: This method should be called once in the end of each period.\n *\n */\n function _distributeMiningReward(address _consensusAddr, address payable _treasury) private {\n uint256 _amount = _miningReward[_consensusAddr];\n if (_amount > 0) {\n if (_unsafeSendRON(_treasury, _amount)) {\n emit MiningRewardDistributed(_consensusAddr, _treasury, _amount);\n return;\n }\n\n emit MiningRewardDistributionFailed(_consensusAddr, _treasury, _amount, address(this).balance);\n }\n }\n\n /**\n * @dev Distribute bonus of staking vesting for the bridge operator.\n *\n * Emits the `BridgeOperatorRewardDistributed` once the reward is distributed successfully.\n * Emits the `BridgeOperatorRewardDistributionFailed` once the contract fails to distribute reward.\n *\n * Note: This method should be called once in the end of each period.\n *\n */\n function _distributeBridgeOperatingReward(\n address _consensusAddr,\n address _bridgeOperator,\n address payable _treasury\n ) private {\n uint256 _amount = _bridgeOperatingReward[_consensusAddr];\n if (_amount > 0) {\n if (_unsafeSendRON(_treasury, _amount)) {\n emit BridgeOperatorRewardDistributed(_consensusAddr, _bridgeOperator, _treasury, _amount);\n return;\n }\n\n emit BridgeOperatorRewardDistributionFailed(\n _consensusAddr,\n _bridgeOperator,\n _treasury,\n _amount,\n address(this).balance\n );\n }\n }\n\n /**\n * @dev Helper function to settle rewards for delegators of `_currentValidators` at the end of each period,\n * then transfer the rewards from this contract to the staking contract, in order to finalize a period.\n *\n * Emits the `StakingRewardDistributed` once the reward is distributed successfully.\n * Emits the `StakingRewardDistributionFailed` once the contract fails to distribute reward.\n *\n * Note: This method should be called once in the end of each period.\n *\n */\n function _settleAndTransferDelegatingRewards(\n uint256 _period,\n address[] memory _currentValidators,\n uint256 _totalDelegatingReward,\n uint256[] memory _delegatingRewards\n ) private {\n IStaking _staking = _stakingContract;\n if (_totalDelegatingReward > 0) {\n if (_unsafeSendRON(payable(address(_staking)), _totalDelegatingReward)) {\n _staking.recordRewards(_currentValidators, _delegatingRewards, _period);\n emit StakingRewardDistributed(_totalDelegatingReward);\n return;\n }\n\n emit StakingRewardDistributionFailed(_totalDelegatingReward, address(this).balance);\n }\n }\n\n /**\n * @dev Transfer the deprecated rewards e.g. the rewards that get deprecated when validator is slashed/maintained,\n * to the staking vesting contract\n *\n * Note: This method should be called once in the end of each period.\n */\n function _recycleDeprecatedRewards() private {\n uint256 _withdrawAmount = _totalDeprecatedReward;\n\n if (_withdrawAmount != 0) {\n address _withdrawTarget = stakingVestingContract();\n\n delete _totalDeprecatedReward;\n\n (bool _success, ) = _withdrawTarget.call{ value: _withdrawAmount }(\n abi.encodeWithSelector(IStakingVesting.receiveRON.selector)\n );\n\n if (_success) {\n emit DeprecatedRewardRecycled(_withdrawTarget, _withdrawAmount);\n } else {\n emit DeprecatedRewardRecycleFailed(_withdrawTarget, _withdrawAmount, address(this).balance);\n }\n }\n }\n\n /**\n * @dev Updates the validator set based on the validator candidates from the Staking contract.\n *\n * Emits the `ValidatorSetUpdated` event.\n * Emits the `BridgeOperatorSetUpdated` event.\n *\n * Note: This method should be called once in the end of each period.\n *\n */\n function _syncValidatorSet(uint256 _newPeriod) private returns (address[] memory _newValidators) {\n _syncCandidateSet();\n uint256[] memory _weights = _stakingContract.getManyStakingTotals(_candidates);\n uint256[] memory _trustedWeights = _roninTrustedOrganizationContract.getConsensusWeights(_candidates);\n uint256 _newValidatorCount;\n (_newValidators, _newValidatorCount) = _pcPickValidatorSet(\n _candidates,\n _weights,\n _trustedWeights,\n _maxValidatorNumber,\n _maxPrioritizedValidatorNumber\n );\n _setNewValidatorSet(_newValidators, _newValidatorCount, _newPeriod);\n emit BridgeOperatorSetUpdated(_newPeriod, getBridgeOperators());\n }\n\n /**\n * @dev Private helper function helps writing the new validator set into the contract storage.\n *\n * Emits the `ValidatorSetUpdated` event.\n *\n * Note: This method should be called once in the end of each period.\n *\n */\n function _setNewValidatorSet(\n address[] memory _newValidators,\n uint256 _newValidatorCount,\n uint256 _newPeriod\n ) private {\n for (uint256 _i = _newValidatorCount; _i < validatorCount; _i++) {\n delete _validatorMap[_validators[_i]];\n delete _validators[_i];\n }\n\n uint256 _count;\n for (uint256 _i = 0; _i < _newValidatorCount; _i++) {\n address _newValidator = _newValidators[_i];\n if (_newValidator == _validators[_count]) {\n _count++;\n continue;\n }\n\n delete _validatorMap[_validators[_count]];\n _validatorMap[_newValidator] = EnumFlags.ValidatorFlag.Both;\n _validators[_count] = _newValidator;\n _count++;\n }\n\n validatorCount = _count;\n emit ValidatorSetUpdated(_newPeriod, _newValidators);\n }\n\n /**\n * @dev Activate/Deactivate the validators from producing blocks, based on their in jail status and maintenance status.\n *\n * Requirements:\n * - This method is called at the end of each epoch\n *\n * Emits the `BlockProducerSetUpdated` event.\n *\n */\n function _revampBlockProducers(uint256 _newPeriod, address[] memory _currentValidators) private {\n bool[] memory _maintainedList = _maintenanceContract.checkManyMaintained(_candidates, block.number + 1);\n\n for (uint _i = 0; _i < _currentValidators.length; _i++) {\n address _currentValidator = _currentValidators[_i];\n bool _isProducerBefore = isBlockProducer(_currentValidator);\n bool _isProducerAfter = !(_jailed(_currentValidator) || _maintainedList[_i]);\n\n if (!_isProducerBefore && _isProducerAfter) {\n _validatorMap[_currentValidator] = _validatorMap[_currentValidator].addFlag(\n EnumFlags.ValidatorFlag.BlockProducer\n );\n continue;\n }\n\n if (_isProducerBefore && !_isProducerAfter) {\n _validatorMap[_currentValidator] = _validatorMap[_currentValidator].removeFlag(\n EnumFlags.ValidatorFlag.BlockProducer\n );\n }\n }\n\n emit BlockProducerSetUpdated(_newPeriod, getBlockProducers());\n }\n\n /**\n * @dev Override `ValidatorInfoStorage-_bridgeOperatorOf`.\n */\n function _bridgeOperatorOf(address _consensusAddr)\n internal\n view\n virtual\n override(CandidateManager, ValidatorInfoStorage)\n returns (address)\n {\n return CandidateManager._bridgeOperatorOf(_consensusAddr);\n }\n}\n" + }, + "contracts/extensions/collections/HasMaintenanceContract.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./HasProxyAdmin.sol\";\nimport \"../../interfaces/collections/IHasMaintenanceContract.sol\";\nimport \"../../interfaces/IMaintenance.sol\";\n\ncontract HasMaintenanceContract is IHasMaintenanceContract, HasProxyAdmin {\n IMaintenance internal _maintenanceContract;\n\n modifier onlyMaintenanceContract() {\n require(\n maintenanceContract() == msg.sender,\n \"HasMaintenanceContract: method caller must be scheduled maintenance contract\"\n );\n _;\n }\n\n /**\n * @inheritdoc IHasMaintenanceContract\n */\n function maintenanceContract() public view override returns (address) {\n return address(_maintenanceContract);\n }\n\n /**\n * @inheritdoc IHasMaintenanceContract\n */\n function setMaintenanceContract(address _addr) external override onlyAdmin {\n require(_addr.code.length > 0, \"HasMaintenanceContract: set to non-contract\");\n _setMaintenanceContract(_addr);\n }\n\n /**\n * @dev Sets the scheduled maintenance contract.\n *\n * Emits the event `MaintenanceContractUpdated`.\n *\n */\n function _setMaintenanceContract(address _addr) internal {\n _maintenanceContract = IMaintenance(_addr);\n emit MaintenanceContractUpdated(_addr);\n }\n}\n" + }, + "contracts/extensions/collections/HasSlashIndicatorContract.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./HasProxyAdmin.sol\";\nimport \"../../interfaces/collections/IHasSlashIndicatorContract.sol\";\nimport \"../../interfaces/slash-indicator/ISlashIndicator.sol\";\n\ncontract HasSlashIndicatorContract is IHasSlashIndicatorContract, HasProxyAdmin {\n ISlashIndicator internal _slashIndicatorContract;\n\n modifier onlySlashIndicatorContract() {\n require(\n slashIndicatorContract() == msg.sender,\n \"HasSlashIndicatorContract: method caller must be slash indicator contract\"\n );\n _;\n }\n\n /**\n * @inheritdoc IHasSlashIndicatorContract\n */\n function slashIndicatorContract() public view override returns (address) {\n return address(_slashIndicatorContract);\n }\n\n /**\n * @inheritdoc IHasSlashIndicatorContract\n */\n function setSlashIndicatorContract(address _addr) external override onlyAdmin {\n require(_addr.code.length > 0, \"HasSlashIndicatorContract: set to non-contract\");\n _setSlashIndicatorContract(_addr);\n }\n\n /**\n * @dev Sets the slash indicator contract.\n *\n * Emits the event `SlashIndicatorContractUpdated`.\n *\n */\n function _setSlashIndicatorContract(address _addr) internal {\n _slashIndicatorContract = ISlashIndicator(_addr);\n emit SlashIndicatorContractUpdated(_addr);\n }\n}\n" + }, + "contracts/extensions/collections/HasStakingVestingContract.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./HasProxyAdmin.sol\";\nimport \"../../interfaces/collections/IHasStakingVestingContract.sol\";\nimport \"../../interfaces/IStakingVesting.sol\";\n\ncontract HasStakingVestingContract is IHasStakingVestingContract, HasProxyAdmin {\n IStakingVesting internal _stakingVestingContract;\n\n modifier onlyStakingVestingContract() {\n require(\n stakingVestingContract() == msg.sender,\n \"HasStakingVestingContract: method caller must be staking vesting contract\"\n );\n _;\n }\n\n /**\n * @inheritdoc IHasStakingVestingContract\n */\n function stakingVestingContract() public view override returns (address) {\n return address(_stakingVestingContract);\n }\n\n /**\n * @inheritdoc IHasStakingVestingContract\n */\n function setStakingVestingContract(address _addr) external override onlyAdmin {\n require(_addr.code.length > 0, \"HasStakingVestingContract: set to non-contract\");\n _setStakingVestingContract(_addr);\n }\n\n /**\n * @dev Sets the staking vesting contract.\n *\n * Emits the event `StakingVestingContractUpdated`.\n *\n */\n function _setStakingVestingContract(address _addr) internal {\n _stakingVestingContract = IStakingVesting(_addr);\n emit StakingVestingContractUpdated(_addr);\n }\n}\n" + }, + "contracts/extensions/RONTransferHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nabstract contract RONTransferHelper {\n /**\n * @dev See `_sendRON`.\n * Reverts if the recipient does not receive RON.\n */\n function _transferRON(address payable _recipient, uint256 _amount) internal {\n require(_sendRON(_recipient, _amount), \"RONTransfer: unable to transfer value, recipient may have reverted\");\n }\n\n /**\n * @dev Send `_amount` RON to the address `_recipient`.\n * Returns whether the recipient receives RON or not.\n * Reverts once the contract balance is insufficient.\n *\n * Note: consider using `ReentrancyGuard` before calling this function.\n *\n */\n function _sendRON(address payable _recipient, uint256 _amount) internal returns (bool _success) {\n require(address(this).balance >= _amount, \"RONTransfer: insufficient balance\");\n return _unsafeSendRON(_recipient, _amount);\n }\n\n /**\n * @dev Unsafe send `_amount` RON to the address `_recipient`. If the sender's balance is insufficient,\n * the call does not revert.\n *\n * Note:\n * - Does not assert whether the balance of sender is sufficient.\n * - Does not assert whether the recipient accepts RON.\n * - Consider using `ReentrancyGuard` before calling this function.\n *\n */\n function _unsafeSendRON(address payable _recipient, uint256 _amount) internal returns (bool _success) {\n (_success, ) = _recipient.call{ value: _amount }(\"\");\n }\n}\n" + }, + "contracts/libraries/EnumFlags.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This library implements checking flag of an enumerated value.\n * The originated idea is inherited from [Enum.HashFlag(Enum)](https://learn.microsoft.com/en-us/dotnet/api/system.enum.hasflag?view=net-6.0) method of C#.\n */\nlibrary EnumFlags {\n enum ValidatorFlag {\n None, // bit(00)\n BlockProducer, // bit(01)\n BridgeOperator, // bit(10)\n Both // bit(11)\n }\n\n function isNone(ValidatorFlag _value) internal pure returns (bool) {\n return uint8(_value) == 0;\n }\n\n /**\n * @dev Checks if `_value` has `_flag`.\n */\n function hasFlag(ValidatorFlag _value, ValidatorFlag _flag) internal pure returns (bool) {\n return (uint8(_value) & uint8(_flag)) != 0;\n }\n\n /**\n * @dev Calculate new value of `_value` after adding `_flag`.\n */\n function addFlag(ValidatorFlag _value, ValidatorFlag _flag) internal pure returns (ValidatorFlag) {\n return ValidatorFlag(uint8(_value) | uint8(_flag));\n }\n\n /**\n * @dev Calculate new value of `_value` after remove `_flag`.\n */\n function removeFlag(ValidatorFlag _value, ValidatorFlag _flag) internal pure returns (ValidatorFlag) {\n return ValidatorFlag(uint8(_value) & ~uint8(_flag));\n }\n}\n" + }, + "contracts/libraries/Math.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\n\npragma solidity ^0.8.0;\n\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns whether the number `c` is in range of [a; b].\n */\n function inRange(\n uint256 c,\n uint256 a,\n uint256 b\n ) internal pure returns (bool) {\n return a <= c && c <= b;\n }\n\n /**\n * @dev Returns whether two inclusive ranges [x1;x2] and [y1;y2] overlap.\n */\n function twoRangeOverlap(\n uint256 x1,\n uint256 x2,\n uint256 y1,\n uint256 y2\n ) internal pure returns (bool) {\n return x1 <= y2 && y1 <= x2;\n }\n\n /**\n * @dev Returns value of a + b; in case result is larger than upperbound, upperbound is returned.\n */\n function addWithUpperbound(\n uint256 a,\n uint256 b,\n uint256 upperbound\n ) internal pure returns (uint256) {\n return min(a + b, upperbound);\n }\n\n /**\n * @dev Returns value of a - b; in case of negative result, 0 is returned.\n */\n function subNonNegative(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - min(a, b);\n }\n}\n" + }, + "contracts/precompile-usages/PrecompileUsageSortValidators.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nabstract contract PrecompileUsageSortValidators {\n /// @dev Gets the address of the precompile of sorting validators\n function precompileSortValidatorsAddress() public view virtual returns (address) {\n return address(0x66);\n }\n\n /**\n * @dev Sorts candidates descending by their weights by calling precompile contract.\n *\n * Note: This function is marked as virtual for being wrapping in mock contract for testing purpose.\n */\n function _pcSortCandidates(address[] memory _candidates, uint256[] memory _weights)\n internal\n view\n virtual\n returns (address[] memory _result)\n {\n address _smc = precompileSortValidatorsAddress();\n bool _success = true;\n\n bytes memory _payload = abi.encodeWithSignature(\"sortValidators(address[],uint256[])\", _candidates, _weights);\n uint256 _payloadLength = _payload.length;\n uint256 _resultLength = 0x20 * _candidates.length + 0x40;\n\n assembly {\n let _payloadStart := add(_payload, 0x20)\n\n if iszero(staticcall(gas(), _smc, _payloadStart, _payloadLength, _result, _resultLength)) {\n _success := 0\n }\n\n if iszero(returndatasize()) {\n _success := 0\n }\n\n _result := add(_result, 0x20)\n }\n\n require(_success, \"PrecompileUsageSortValidators: call to precompile fails\");\n }\n}\n" + }, + "contracts/precompile-usages/PrecompileUsagePickValidatorSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nabstract contract PrecompileUsagePickValidatorSet {\n /// @dev Gets the address of the precompile of picking validator set\n function precompilePickValidatorSetAddress() public view virtual returns (address) {\n return address(0x68);\n }\n\n /**\n * @dev Sorts and arranges to return a new validator set.\n *\n * Note: The recover process is done by pre-compiled contract. This function is marked as\n * virtual for implementing mocking contract for testing purpose.\n */\n function _pcPickValidatorSet(\n address[] memory _candidates,\n uint256[] memory _weights,\n uint256[] memory _trustedWeights,\n uint256 _maxValidatorNumber,\n uint256 _maxPrioritizedValidatorNumber\n ) internal view virtual returns (address[] memory _result, uint256 _newValidatorCount) {\n address _smc = precompilePickValidatorSetAddress();\n bytes memory _payload = abi.encodeWithSignature(\n \"pickValidatorSet(address[],uint256[],uint256[],uint256,uint256)\",\n _candidates,\n _weights,\n _trustedWeights,\n _maxValidatorNumber,\n _maxPrioritizedValidatorNumber\n );\n bool _success = true;\n\n uint256 _payloadLength = _payload.length;\n uint256 _resultLength = 0x20 * _candidates.length + 0x40;\n\n assembly {\n let _payloadStart := add(_payload, 0x20)\n\n if iszero(staticcall(gas(), _smc, _payloadStart, _payloadLength, _result, _resultLength)) {\n _success := 0\n }\n\n if iszero(returndatasize()) {\n _success := 0\n }\n\n _result := add(_result, 0x20)\n }\n\n require(_success, \"PrecompileUsagePickValidatorSet: call to precompile fails\");\n\n _newValidatorCount = _result.length;\n }\n}\n" + }, + "contracts/ronin/validator/storage-fragments/CommonStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../../interfaces/validator/info-fragments/ICommonInfo.sol\";\nimport \"./JailingStorage.sol\";\nimport \"./TimingStorage.sol\";\nimport \"./ValidatorInfoStorage.sol\";\n\nabstract contract CommonStorage is ICommonInfo, TimingStorage, JailingStorage, ValidatorInfoStorage {\n /// @dev Mapping from consensus address => pending reward from producing block\n mapping(address => uint256) internal _miningReward;\n /// @dev Mapping from consensus address => pending reward from delegating\n mapping(address => uint256) internal _delegatingReward;\n\n /// @dev The total reward for bridge operators\n uint256 internal _totalBridgeReward;\n /// @dev Mapping from consensus address => pending reward for being bridge operator\n mapping(address => uint256) internal _bridgeOperatingReward;\n\n /// @dev The deprecated reward that has not been withdrawn by admin\n uint256 internal _totalDeprecatedReward;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[49] private ______gap;\n\n /**\n * @inheritdoc ICommonInfo\n */\n function totalDeprecatedReward() external view override returns (uint256) {\n return _totalDeprecatedReward;\n }\n\n /**\n * @inheritdoc ITimingInfo\n */\n function epochOf(uint256 _block)\n public\n view\n virtual\n override(ITimingInfo, JailingStorage, TimingStorage)\n returns (uint256)\n {\n return TimingStorage.epochOf(_block);\n }\n\n /**\n * @inheritdoc ITimingInfo\n */\n function currentPeriod() public view virtual override(ITimingInfo, JailingStorage, TimingStorage) returns (uint256) {\n return TimingStorage.currentPeriod();\n }\n}\n" + }, + "contracts/ronin/validator/CandidateManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"../../extensions/collections/HasStakingContract.sol\";\nimport \"../../extensions/consumers/PercentageConsumer.sol\";\nimport \"../../interfaces/validator/ICandidateManager.sol\";\nimport \"../../interfaces/staking/IStaking.sol\";\n\nabstract contract CandidateManager is ICandidateManager, PercentageConsumer, HasStakingContract {\n /// @dev Maximum number of validator candidate\n uint256 private _maxValidatorCandidate;\n\n /// @dev The validator candidate array\n address[] internal _candidates;\n /// @dev Mapping from candidate consensus address => bitwise negation of validator index in `_candidates`\n mapping(address => uint256) internal _candidateIndex;\n /// @dev Mapping from candidate consensus address => their info\n mapping(address => ValidatorCandidate) internal _candidateInfo;\n\n /**\n * @dev The minimum offset in day from current date to the effective date of a new commission schedule.\n * Value of 1 means the change gets affected at the beginning of the following day.\n **/\n uint256 internal _minEffectiveDaysOnwards;\n /// @dev Mapping from candidate consensus address => schedule commission change.\n mapping(address => CommissionSchedule) internal _candidateCommissionChangeSchedule;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[48] private ______gap;\n\n /**\n * @inheritdoc ICandidateManager\n */\n function maxValidatorCandidate() public view override returns (uint256) {\n return _maxValidatorCandidate;\n }\n\n /**\n * @inheritdoc ICandidateManager\n */\n function minEffectiveDaysOnwards() external view override returns (uint256) {\n return _minEffectiveDaysOnwards;\n }\n\n /**\n * @inheritdoc ICandidateManager\n */\n function setMaxValidatorCandidate(uint256 _number) external override onlyAdmin {\n _setMaxValidatorCandidate(_number);\n }\n\n /**\n * @inheritdoc ICandidateManager\n */\n function setMinEffectiveDaysOnwards(uint256 _numOfDays) external override onlyAdmin {\n _setMinEffectiveDaysOnwards(_numOfDays);\n }\n\n /**\n * @inheritdoc ICandidateManager\n */\n function grantValidatorCandidate(\n address _candidateAdmin,\n address _consensusAddr,\n address payable _treasuryAddr,\n address _bridgeOperatorAddr,\n uint256 _commissionRate\n ) external override onlyStakingContract {\n uint256 _length = _candidates.length;\n require(_length < maxValidatorCandidate(), \"CandidateManager: exceeds maximum number of candidates\");\n require(!isValidatorCandidate(_consensusAddr), \"CandidateManager: query for already existent candidate\");\n require(_commissionRate <= _MAX_PERCENTAGE, \"CandidateManager: invalid comission rate\");\n\n for (uint _i = 0; _i < _candidates.length; _i++) {\n ValidatorCandidate storage existentInfo = _candidateInfo[_candidates[_i]];\n\n if (_candidateAdmin == existentInfo.admin) {\n revert(\n string(\n abi.encodePacked(\n \"CandidateManager: candidate admin address \",\n Strings.toHexString(uint160(_candidateAdmin), 20),\n \" is already exist\"\n )\n )\n );\n }\n\n if (_treasuryAddr == existentInfo.treasuryAddr) {\n revert(\n string(\n abi.encodePacked(\n \"CandidateManager: treasury address \",\n Strings.toHexString(uint160(address(_treasuryAddr)), 20),\n \" is already exist\"\n )\n )\n );\n }\n\n if (_bridgeOperatorAddr == existentInfo.bridgeOperatorAddr) {\n revert(\n string(\n abi.encodePacked(\n \"CandidateManager: bridge operator address \",\n Strings.toHexString(uint160(_bridgeOperatorAddr), 20),\n \" is already exist\"\n )\n )\n );\n }\n }\n\n _candidateIndex[_consensusAddr] = ~_length;\n _candidates.push(_consensusAddr);\n\n ValidatorCandidate storage _info = _candidateInfo[_consensusAddr];\n _info.admin = _candidateAdmin;\n _info.consensusAddr = _consensusAddr;\n _info.treasuryAddr = _treasuryAddr;\n _info.bridgeOperatorAddr = _bridgeOperatorAddr;\n _info.commissionRate = _commissionRate;\n emit CandidateGranted(_consensusAddr, _treasuryAddr, _candidateAdmin, _bridgeOperatorAddr);\n }\n\n /**\n * @inheritdoc ICandidateManager\n */\n function requestRevokeCandidate(address _consensusAddr, uint256 _secsLeft) external override onlyStakingContract {\n require(isValidatorCandidate(_consensusAddr), \"CandidateManager: query for non-existent candidate\");\n ValidatorCandidate storage _info = _candidateInfo[_consensusAddr];\n require(_info.revokingTimestamp == 0, \"CandidateManager: already requested before\");\n\n uint256 _revokingTimestamp = block.timestamp + _secsLeft;\n _info.revokingTimestamp = _revokingTimestamp;\n emit CandidateRevokingTimestampUpdated(_consensusAddr, _revokingTimestamp);\n }\n\n /**\n * @inheritdoc ICandidateManager\n */\n function execRequestUpdateCommissionRate(\n address _consensusAddr,\n uint256 _effectiveDaysOnwards,\n uint256 _commissionRate\n ) external override onlyStakingContract {\n require(\n _candidateCommissionChangeSchedule[_consensusAddr].effectiveTimestamp == 0,\n \"CandidateManager: commission change schedule exists\"\n );\n require(_commissionRate <= _MAX_PERCENTAGE, \"CandidateManager: invalid commission rate\");\n require(_effectiveDaysOnwards >= _minEffectiveDaysOnwards, \"CandidateManager: invalid effective date\");\n\n CommissionSchedule storage _schedule = _candidateCommissionChangeSchedule[_consensusAddr];\n uint256 _effectiveTimestamp = ((block.timestamp / 1 days) + _effectiveDaysOnwards) * 1 days;\n _schedule.effectiveTimestamp = _effectiveTimestamp;\n _schedule.commissionRate = _commissionRate;\n\n emit CommissionRateUpdateScheduled(_consensusAddr, _effectiveTimestamp, _commissionRate);\n }\n\n /**\n * @inheritdoc ICandidateManager\n */\n function isValidatorCandidate(address _addr) public view override returns (bool) {\n return _candidateIndex[_addr] != 0;\n }\n\n /**\n * @inheritdoc ICandidateManager\n */\n function getCandidateInfos() external view override returns (ValidatorCandidate[] memory _list) {\n _list = new ValidatorCandidate[](_candidates.length);\n for (uint _i = 0; _i < _list.length; _i++) {\n _list[_i] = _candidateInfo[_candidates[_i]];\n }\n }\n\n /**\n * @inheritdoc ICandidateManager\n */\n function getCandidateInfo(address _candidate) external view override returns (ValidatorCandidate memory) {\n require(isValidatorCandidate(_candidate), \"CandidateManager: query for non-existent candidate\");\n return _candidateInfo[_candidate];\n }\n\n /**\n * @inheritdoc ICandidateManager\n */\n function getValidatorCandidates() public view override returns (address[] memory) {\n return _candidates;\n }\n\n /**\n * @inheritdoc ICandidateManager\n */\n function getCommissionChangeSchedule(address _candidate) external view override returns (CommissionSchedule memory) {\n return _candidateCommissionChangeSchedule[_candidate];\n }\n\n /**\n * @dev Removes unsastisfied candidates, the ones who have insufficient minimum candidate staking amount,\n * or the ones who requested to renounce their candidate role.\n *\n * Emits the event `CandidatesRevoked` when a candidate is revoked.\n *\n */\n function _syncCandidateSet() internal {\n IStaking _staking = _stakingContract;\n uint256 _waitingSecsToRevoke = _staking.waitingSecsToRevoke();\n uint256 _minStakingAmount = _staking.minValidatorStakingAmount();\n uint256[] memory _selfStakings = _staking.getManySelfStakings(_candidates);\n\n uint256 _length = _candidates.length;\n uint256 _unsatisfiedCount;\n address[] memory _unsatisfiedCandidates = new address[](_length);\n\n {\n uint256 _i;\n address _addr;\n ValidatorCandidate storage _info;\n while (_i < _length) {\n _addr = _candidates[_i];\n _info = _candidateInfo[_addr];\n\n // Checks for under-balance status of candidates\n bool _hasTopupDeadline = _info.topupDeadline != 0;\n if (_selfStakings[_i] < _minStakingAmount) {\n // Updates deadline on the first time unsatisfied the staking amount condition\n if (!_hasTopupDeadline) {\n uint256 _topupDeadline = block.timestamp + _waitingSecsToRevoke;\n _info.topupDeadline = _topupDeadline;\n emit CandidateTopupDeadlineUpdated(_addr, _topupDeadline);\n }\n } else if (_hasTopupDeadline) {\n // Removes the deadline if the staking amount condition is satisfied\n delete _info.topupDeadline;\n emit CandidateTopupDeadlineUpdated(_addr, 0);\n }\n\n // Removes unsastisfied candidates\n bool _revokingActivated = _info.revokingTimestamp != 0 && _info.revokingTimestamp <= block.timestamp;\n bool _topupDeadlineMissed = _info.topupDeadline != 0 && _info.topupDeadline <= block.timestamp;\n if (_revokingActivated || _topupDeadlineMissed) {\n _selfStakings[_i] = _selfStakings[--_length];\n _unsatisfiedCandidates[_unsatisfiedCount++] = _addr;\n _removeCandidate(_addr);\n continue;\n }\n\n // Checks for schedule of commission change and updates commission rate\n uint256 _scheduleTimestamp = _candidateCommissionChangeSchedule[_addr].effectiveTimestamp;\n if (_scheduleTimestamp != 0 && _scheduleTimestamp <= block.timestamp) {\n uint256 _commisionRate = _candidateCommissionChangeSchedule[_addr].commissionRate;\n delete _candidateCommissionChangeSchedule[_addr];\n _info.commissionRate = _commisionRate;\n emit CommissionRateUpdated(_addr, _commisionRate);\n }\n\n _i++;\n }\n }\n\n if (_unsatisfiedCount > 0) {\n assembly {\n mstore(_unsatisfiedCandidates, _unsatisfiedCount)\n }\n emit CandidatesRevoked(_unsatisfiedCandidates);\n _staking.deprecatePools(_unsatisfiedCandidates);\n }\n }\n\n /**\n * @inheritdoc ICandidateManager\n */\n function isCandidateAdmin(address _candidate, address _admin) external view override returns (bool) {\n return _candidateInfo[_candidate].admin == _admin;\n }\n\n /**\n * @dev Override `ValidatorInfoStorage-_bridgeOperatorOf`.\n */\n function _bridgeOperatorOf(address _consensusAddr) internal view virtual returns (address) {\n return _candidateInfo[_consensusAddr].bridgeOperatorAddr;\n }\n\n /**\n * @dev Sets the maximum number of validator candidate.\n *\n * Emits the `MaxValidatorCandidateUpdated` event.\n *\n */\n function _setMaxValidatorCandidate(uint256 _threshold) internal {\n _maxValidatorCandidate = _threshold;\n emit MaxValidatorCandidateUpdated(_threshold);\n }\n\n /**\n * @dev Sets the minimum number of days onwards to the effective date of commission rate change.\n *\n * Emits the `MinEffectiveDaysOnwardsUpdated` event.\n *\n */\n function _setMinEffectiveDaysOnwards(uint256 _numOfDays) internal {\n require(_numOfDays >= 1, \"CandidateManager: invalid min effective days onwards\");\n _minEffectiveDaysOnwards = _numOfDays;\n emit MinEffectiveDaysOnwardsUpdated(_numOfDays);\n }\n\n /**\n * @dev Removes the candidate.\n */\n function _removeCandidate(address _addr) private {\n uint256 _idx = _candidateIndex[_addr];\n if (_idx == 0) {\n return;\n }\n\n delete _candidateInfo[_addr];\n delete _candidateIndex[_addr];\n delete _candidateCommissionChangeSchedule[_addr];\n\n address _lastCandidate = _candidates[_candidates.length - 1];\n\n if (_lastCandidate != _addr) {\n _candidateIndex[_lastCandidate] = _idx;\n _candidates[~_idx] = _lastCandidate;\n }\n\n _candidates.pop();\n }\n}\n" + }, + "contracts/interfaces/collections/IHasMaintenanceContract.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface IHasMaintenanceContract {\n /// @dev Emitted when the maintenance contract is updated.\n event MaintenanceContractUpdated(address);\n\n /**\n * @dev Returns the maintenance contract.\n */\n function maintenanceContract() external view returns (address);\n\n /**\n * @dev Sets the maintenance contract.\n *\n * Requirements:\n * - The method caller is admin.\n * - The new address is a contract.\n *\n * Emits the event `MaintenanceContractUpdated`.\n *\n */\n function setMaintenanceContract(address) external;\n}\n" + }, + "contracts/interfaces/IMaintenance.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface IMaintenance {\n struct Schedule {\n uint256 from;\n uint256 to;\n uint256 lastUpdatedBlock;\n }\n\n /// @dev Emitted when a maintenance is scheduled.\n event MaintenanceScheduled(address indexed consensusAddr, Schedule);\n /// @dev Emitted when the maintenance config is updated.\n event MaintenanceConfigUpdated(\n uint256 minMaintenanceDurationInBlock,\n uint256 maxMaintenanceDurationInBlock,\n uint256 minOffsetToStartSchedule,\n uint256 maxOffsetToStartSchedule,\n uint256 maxSchedules\n );\n\n /**\n * @dev Returns whether the validator `_consensusAddr` maintained at the block number `_block`.\n */\n function checkMaintained(address _consensusAddr, uint256 _block) external view returns (bool);\n\n /**\n * @dev Returns whether the validator `_consensusAddr` maintained in the inclusive range [`_fromBlock`, `_toBlock`] of blocks.\n */\n function checkMaintainedInBlockRange(\n address _consensusAddr,\n uint256 _fromBlock,\n uint256 _toBlock\n ) external view returns (bool);\n\n /**\n * @dev Returns the bool array indicating the validators maintained at block number `_block` or not.\n */\n function checkManyMaintained(address[] calldata _addrList, uint256 _block) external view returns (bool[] memory);\n\n /**\n * @dev Returns a bool array indicating the validators maintained in the inclusive range [`_fromBlock`, `_toBlock`] of blocks or not.\n */\n function checkManyMaintainedInBlockRange(\n address[] calldata _addrList,\n uint256 _fromBlock,\n uint256 _toBlock\n ) external view returns (bool[] memory);\n\n /**\n * @dev Returns whether the validator `_consensusAddr` has scheduled.\n */\n function checkScheduled(address _consensusAddr) external view returns (bool);\n\n /**\n * @dev Returns the detailed schedule of the validator `_consensusAddr`.\n */\n function getSchedule(address _consensusAddr) external view returns (Schedule memory);\n\n /**\n * @dev Returns the total of current schedules.\n */\n function totalSchedules() external view returns (uint256 _count);\n\n /**\n * @dev Sets the duration restriction, start time restriction, and max allowed for maintenance.\n *\n * Requirements:\n * - The method caller is admin.\n * - The max duration is larger than the min duration.\n * - The max offset is larger than the min offset.\n *\n * Emits the event `MaintenanceConfigUpdated`.\n *\n */\n function setMaintenanceConfig(\n uint256 _minMaintenanceDurationInBlock,\n uint256 _maxMaintenanceDurationInBlock,\n uint256 _minOffsetToStartSchedule,\n uint256 _maxOffsetToStartSchedule,\n uint256 _maxSchedules\n ) external;\n\n /**\n * @dev Returns the min duration for maintenance in block.\n */\n function minMaintenanceDurationInBlock() external view returns (uint256);\n\n /**\n * @dev Returns the max duration for maintenance in block.\n */\n function maxMaintenanceDurationInBlock() external view returns (uint256);\n\n /**\n * @dev The offset to the min block number that the schedule can start\n */\n function minOffsetToStartSchedule() external view returns (uint256);\n\n /**\n * @dev The offset to the max block number that the schedule can start\n */\n function maxOffsetToStartSchedule() external view returns (uint256);\n\n /**\n * @dev Returns the max number of scheduled maintenances.\n */\n function maxSchedules() external view returns (uint256);\n\n /**\n * @dev Schedules for maintenance from `_startedAtBlock` to `_startedAtBlock`.\n *\n * Requirements:\n * - The candidate `_consensusAddr` is the block producer.\n * - The method caller is candidate admin of the candidate `_consensusAddr`.\n * - The candidate `_consensusAddr` has no schedule yet or the previous is done.\n * - The total number of schedules is not larger than `maxSchedules()`.\n * - The start block must be at least `minOffsetToStartSchedule()` and at most `maxOffsetToStartSchedule()` blocks from the current block.\n * - The end block is larger than the start block.\n * - The scheduled duration is larger than the `minMaintenanceDurationInBlock()` and less than the `maxMaintenanceDurationInBlock()`.\n * - The start block is at the start of an epoch.\n * - The end block is at the end of an epoch.\n *\n * Emits the event `MaintenanceScheduled`.\n *\n */\n function schedule(\n address _consensusAddr,\n uint256 _startedAtBlock,\n uint256 _endedAtBlock\n ) external;\n}\n" + }, + "contracts/interfaces/collections/IHasSlashIndicatorContract.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface IHasSlashIndicatorContract {\n /// @dev Emitted when the slash indicator contract is updated.\n event SlashIndicatorContractUpdated(address);\n\n /**\n * @dev Returns the slash indicator contract.\n */\n function slashIndicatorContract() external view returns (address);\n\n /**\n * @dev Sets the slash indicator contract.\n *\n * Requirements:\n * - The method caller is admin.\n * - The new address is a contract.\n *\n * Emits the event `SlashIndicatorContractUpdated`.\n *\n */\n function setSlashIndicatorContract(address) external;\n}\n" + }, + "contracts/interfaces/slash-indicator/ISlashIndicator.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"./ISlashDoubleSign.sol\";\nimport \"./ISlashBridgeVoting.sol\";\nimport \"./ISlashBridgeOperator.sol\";\nimport \"./ISlashUnavailability.sol\";\nimport \"./ICreditScore.sol\";\n\ninterface ISlashIndicator is\n ISlashDoubleSign,\n ISlashBridgeVoting,\n ISlashBridgeOperator,\n ISlashUnavailability,\n ICreditScore\n{}\n" + }, + "contracts/interfaces/slash-indicator/ISlashDoubleSign.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"./IBaseSlash.sol\";\n\ninterface ISlashDoubleSign is IBaseSlash {\n /**\n * @dev Emitted when the configs to slash double sign is updated. See the method `getDoubleSignSlashingConfigs`\n * for param details.\n */\n event DoubleSignSlashingConfigsUpdated(uint256 slashDoubleSignAmount, uint256 doubleSigningJailUntilBlock);\n\n /**\n * @dev Slashes for double signing.\n *\n * Requirements:\n * - The method caller is coinbase.\n *\n * Emits the event `Slashed` if the double signing evidence of the two headers valid.\n */\n function slashDoubleSign(\n address _validatorAddr,\n bytes calldata _header1,\n bytes calldata _header2\n ) external;\n\n /**\n * @dev Returns the configs related to block producer slashing.\n *\n * @return _slashDoubleSignAmount The amount of RON to slash double sign.\n * @return _doubleSigningJailUntilBlock The block number that the punished validator will be jailed until, due to\n * double signing.\n *\n */\n function getDoubleSignSlashingConfigs()\n external\n view\n returns (uint256 _slashDoubleSignAmount, uint256 _doubleSigningJailUntilBlock);\n\n /**\n * @dev Sets the configs to slash block producers.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the event `DoubleSignSlashingConfigsUpdated`.\n *\n * @param _slashAmount The amount of RON to slash double sign.\n * @param _jailUntilBlock The block number that the punished validator will be jailed until, due to double signing.\n *\n */\n function setDoubleSignSlashingConfigs(uint256 _slashAmount, uint256 _jailUntilBlock) external;\n}\n" + }, + "contracts/interfaces/slash-indicator/ISlashBridgeVoting.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"./IBaseSlash.sol\";\n\ninterface ISlashBridgeVoting is IBaseSlash {\n /**\n * @dev Emitted when the configs to slash bridge voting is updated. See the method `getBridgeVotingSlashingConfigs` for param\n * details.\n */\n event BridgeVotingSlashingConfigsUpdated(uint256 bridgeVotingThreshold, uint256 bridgeVotingSlashAmount);\n\n /**\n * @dev Slashes for bridge voter governance.\n *\n * Emits the event `Slashed`.\n */\n function slashBridgeVoting(address _consensusAddr) external;\n\n /**\n * @dev Returns the configs related to bridge voting slashing.\n *\n * @return _bridgeVotingThreshold The threshold to slash when a trusted organization does not vote for bridge\n * operators.\n * @return _bridgeVotingSlashAmount The amount of RON to slash bridge voting.\n *\n */\n function getBridgeVotingSlashingConfigs()\n external\n view\n returns (uint256 _bridgeVotingThreshold, uint256 _bridgeVotingSlashAmount);\n\n /**\n * @dev Sets the configs to slash bridge voting.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the event `BridgeVotingSlashingConfigsUpdated`.\n *\n * @param _threshold The threshold to slash when a trusted organization does not vote for bridge operators.\n * @param _slashAmount The amount of RON to slash bridge voting.\n *\n */\n function setBridgeVotingSlashingConfigs(uint256 _threshold, uint256 _slashAmount) external;\n}\n" + }, + "contracts/interfaces/slash-indicator/ISlashBridgeOperator.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface ISlashBridgeOperator {\n /**\n * @dev Emitted when the configs to slash bridge operator is updated. See the method\n * `getBridgeOperatorSlashingConfigs` for param details.\n */\n event BridgeOperatorSlashingConfigsUpdated(\n uint256 missingVotesRatioTier1,\n uint256 missingVotesRatioTier2,\n uint256 jailDurationForMissingVotesRatioTier2,\n uint256 skipBridgeOperatorSlashingThreshold\n );\n\n /**\n * @dev Returns the configs related to bridge operator slashing.\n *\n * @return _missingVotesRatioTier1 The bridge reward will be deprecated if (s)he missed more than this ratio.\n * @return _missingVotesRatioTier2 The bridge reward and mining reward will be deprecated and the corresponding\n * block producer will be put in jail if (s)he misses more than this ratio.\n * @return _jailDurationForMissingVotesRatioTier2 The number of blocks to jail the corresponding block producer when\n * its bridge operator is slashed tier-2.\n * @return _skipBridgeOperatorSlashingThreshold The threshold to skip slashing the bridge operator in case the total\n * number of votes in the bridge is too small.\n *\n */\n function getBridgeOperatorSlashingConfigs()\n external\n view\n returns (\n uint256 _missingVotesRatioTier1,\n uint256 _missingVotesRatioTier2,\n uint256 _jailDurationForMissingVotesRatioTier2,\n uint256 _skipBridgeOperatorSlashingThreshold\n );\n\n /**\n * @dev Sets the configs to slash bridge operators.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the event `BridgeOperatorSlashingConfigsUpdated`.\n *\n * @param _ratioTier1 The bridge reward will be deprecated if (s)he missed more than this ratio. Values 0-10,000 map\n * to 0%-100%.\n * @param _ratioTier2 The bridge reward and mining reward will be deprecated and the corresponding block producer will\n * be put in jail if (s)he misses more than this ratio. Values 0-10,000 map to 0%-100%.\n * @param _jailDurationTier2 The number of blocks to jail the corresponding block producer when its bridge operator is\n * slashed tier-2.\n * @param _skipSlashingThreshold The threshold to skip slashing the bridge operator in case the total number of votes\n * in the bridge is too small.\n *\n */\n function setBridgeOperatorSlashingConfigs(\n uint256 _ratioTier1,\n uint256 _ratioTier2,\n uint256 _jailDurationTier2,\n uint256 _skipSlashingThreshold\n ) external;\n}\n" + }, + "contracts/interfaces/slash-indicator/ISlashUnavailability.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"./IBaseSlash.sol\";\n\ninterface ISlashUnavailability is IBaseSlash {\n /**\n * @dev Emitted when the configs to slash bridge operator is updated. See the method `getUnavailabilitySlashingConfigs`\n * for param details.\n */\n event UnavailabilitySlashingConfigsUpdated(\n uint256 unavailabilityTier1Threshold,\n uint256 unavailabilityTier2Threshold,\n uint256 slashAmountForUnavailabilityTier2Threshold,\n uint256 jailDurationForUnavailabilityTier2Threshold\n );\n\n /**\n * @dev Returns the last block that a block producer is slashed for unavailability.\n */\n function lastUnavailabilitySlashedBlock() external view returns (uint256);\n\n /**\n * @dev Slashes for unavailability by increasing the counter of block producer `_consensusAddr`.\n *\n * Requirements:\n * - The method caller is coinbase.\n *\n * Emits the event `Slashed` when the threshold is reached.\n *\n */\n function slashUnavailability(address _consensusAddr) external;\n\n /**\n * @dev Returns the current unavailability indicator of a block producer.\n */\n function currentUnavailabilityIndicator(address _validator) external view returns (uint256);\n\n /**\n * @dev Retursn the unavailability indicator in the period `_period` of a block producer.\n */\n function getUnavailabilityIndicator(address _validator, uint256 _period) external view returns (uint256);\n\n /**\n * @dev Returns the configs related to block producer slashing.\n *\n * @return _unavailabilityTier1Threshold The mining reward will be deprecated, if (s)he missed more than this\n * threshold.\n * @return _unavailabilityTier2Threshold The mining reward will be deprecated, (s)he will be put in jailed, and will\n * be deducted self-staking if (s)he misses more than this threshold.\n * @return _slashAmountForUnavailabilityTier2Threshold The amount of RON to deduct from self-staking of a block\n * producer when (s)he is slashed tier-2.\n * @return _jailDurationForUnavailabilityTier2Threshold The number of blocks to jail a block producer when (s)he is\n * slashed tier-2.\n *\n */\n function getUnavailabilitySlashingConfigs()\n external\n view\n returns (\n uint256 _unavailabilityTier1Threshold,\n uint256 _unavailabilityTier2Threshold,\n uint256 _slashAmountForUnavailabilityTier2Threshold,\n uint256 _jailDurationForUnavailabilityTier2Threshold\n );\n\n /**\n * @dev Sets the configs to slash block producers.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the event `BridgeOperatorSlashingConfigsUpdated`.\n *\n * @param _tier1Threshold The mining reward will be deprecated, if (s)he missed more than this threshold.\n * @param _tier2Threshold The mining reward will be deprecated, (s)he will be put in jailed, and will be deducted\n * self-staking if (s)he misses more than this threshold.\n * @param _slashAmountForTier2Threshold The amount of RON to deduct from self-staking of a block producer when (s)he\n * is slashed tier-2.\n * @param _jailDurationForTier2Threshold The number of blocks to jail a block producer when (s)he is slashed tier-2.\n *\n */\n function setUnavailabilitySlashingConfigs(\n uint256 _tier1Threshold,\n uint256 _tier2Threshold,\n uint256 _slashAmountForTier2Threshold,\n uint256 _jailDurationForTier2Threshold\n ) external;\n}\n" + }, + "contracts/interfaces/slash-indicator/ICreditScore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface ICreditScore {\n /// @dev Emitted when the configs to credit score is updated. See the method `setCreditScoreConfigs` for param details.\n event CreditScoreConfigsUpdated(\n uint256 gainCreditScore,\n uint256 maxCreditScore,\n uint256 bailOutCostMultiplier,\n uint256 cutOffPercentageAfterBailout\n );\n /// @dev Emitted the credit score of validators is updated\n event CreditScoresUpdated(address[] validators, uint256[] creditScores);\n /// @dev Emitted when a validator bailed out of jail\n event BailedOut(address indexed validator, uint256 period);\n\n /**\n * @dev Updates the credit score for the validators.\n *\n * Requirements:\n * - Only validator contract can call this method.\n * - This method is only called at the end of each period.\n *\n * Emits the event `CreditScoresUpdated`.\n *\n */\n function updateCreditScores(address[] calldata _validators, uint256 _period) external;\n\n /**\n * @dev A slashed validator use this method to get out of jail.\n *\n * Requirements:\n * - The `_consensusAddr` must be a validator.\n * - Only validator's admin can call this method.\n *\n * Emits the event `BailedOut`.\n *\n */\n function bailOut(address _consensusAddr) external;\n\n /**\n * @dev Sets the configs to credit score.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the event `CreditScoreConfigsUpdated`.\n *\n * @param _gainScore The score to gain per period.\n * @param _maxScore The max number of credit score that a validator can hold.\n * @param _bailOutMultiplier The number that will be multiplied with the remaining jailed time to get the cost of bailing out.\n * @param _cutOffPercentage The percentage of reward that the block producer will be cut off from until the end of the period after bailing out.\n *\n */\n function setCreditScoreConfigs(\n uint256 _gainScore,\n uint256 _maxScore,\n uint256 _bailOutMultiplier,\n uint256 _cutOffPercentage\n ) external;\n\n /**\n * @dev Returns the configs related to credit score.\n *\n * @return _gainCreditScore The score to gain per period.\n * @return _maxCreditScore The max number of credit score that a validator can hold.\n * @return _bailOutCostMultiplier The number that will be multiplied with the remaining jailed time to get the cost of bailing out.\n * @return _cutOffPercentageAfterBailout The percentage of reward that the block producer will be cut off from until the end of the period after bailing out.\n *\n */\n function getCreditScoreConfigs()\n external\n view\n returns (\n uint256 _gainCreditScore,\n uint256 _maxCreditScore,\n uint256 _bailOutCostMultiplier,\n uint256 _cutOffPercentageAfterBailout\n );\n\n /**\n * @dev Returns the current credit score of the validator.\n */\n function getCreditScore(address _validator) external view returns (uint256);\n\n /**\n * @dev Returns the current credit score of a list of validators.\n */\n function getManyCreditScores(address[] calldata _validators) external view returns (uint256[] memory _resultList);\n\n /**\n * @dev Returns the whether the `_validator` has been bailed out at the `_period`.\n */\n function checkBailedOutAtPeriod(address _validator, uint256 _period) external view returns (bool);\n}\n" + }, + "contracts/interfaces/slash-indicator/IBaseSlash.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface IBaseSlash {\n enum SlashType {\n UNKNOWN,\n UNAVAILABILITY_TIER_1,\n UNAVAILABILITY_TIER_2,\n DOUBLE_SIGNING,\n BRIDGE_VOTING,\n BRIDGE_OPERATOR_MISSING_VOTE_TIER_1,\n BRIDGE_OPERATOR_MISSING_VOTE_TIER_2\n }\n\n /// @dev Emitted when the validator is slashed.\n event Slashed(address indexed validator, SlashType slashType, uint256 period);\n}\n" + }, + "contracts/interfaces/collections/IHasStakingVestingContract.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface IHasStakingVestingContract {\n /// @dev Emitted when the staking vesting contract is updated.\n event StakingVestingContractUpdated(address);\n\n /**\n * @dev Returns the staking vesting contract.\n */\n function stakingVestingContract() external view returns (address);\n\n /**\n * @dev Sets the staking vesting contract.\n *\n * Requirements:\n * - The method caller is admin.\n * - The new address is a contract.\n *\n * Emits the event `StakingVestingContractUpdated`.\n *\n */\n function setStakingVestingContract(address) external;\n}\n" + }, + "contracts/interfaces/IStakingVesting.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface IStakingVesting {\n /// @dev Emitted when the block bonus for block producer is transferred.\n event BonusTransferred(\n uint256 indexed blockNumber,\n address indexed recipient,\n uint256 blockProducerAmount,\n uint256 bridgeOperatorAmount\n );\n /// @dev Emitted when the transfer of block bonus for block producer is failed.\n event BonusTransferFailed(\n uint256 indexed blockNumber,\n address indexed recipient,\n uint256 blockProducerAmount,\n uint256 bridgeOperatorAmount,\n uint256 contractBalance\n );\n /// @dev Emitted when the block bonus for block producer is updated\n event BlockProducerBonusPerBlockUpdated(uint256);\n /// @dev Emitted when the block bonus for bridge operator is updated\n event BridgeOperatorBonusPerBlockUpdated(uint256);\n\n /**\n * @dev Returns the bonus amount for the block producer at `_block`.\n */\n function blockProducerBlockBonus(uint256 _block) external view returns (uint256);\n\n /**\n * @dev Returns the bonus amount for the bridge validator at `_block`.\n */\n function bridgeOperatorBlockBonus(uint256 _block) external view returns (uint256);\n\n /**\n * @dev Receives RON from any address.\n */\n function receiveRON() external payable;\n\n /**\n * @dev Returns the last block number that the staking vesting is sent.\n */\n function lastBlockSendingBonus() external view returns (uint256);\n\n /**\n * @dev Transfers the staking vesting for the block producer and the bridge operator whenever a new block is mined.\n *\n * Requirements:\n * - The method caller must be validator contract.\n * - The method must be called only once per block.\n *\n * Emits the event `BonusTransferred` or `BonusTransferFailed`.\n *\n * Notes:\n * - The method does not revert when the contract balance is insufficient to send bonus. This assure the submit reward method\n * will not be reverted, and the underlying nodes does not hang.\n *\n * @param _forBlockProducer Indicates whether requesting the bonus for the block procucer, in case of being in jail or relevance.\n * @param _forBridgeOperator Indicates whether requesting the bonus for the bridge operator.\n *\n * @return _success Whether the transfer is successfully. This returns false mostly because this contract is out of balance.\n * @return _blockProducerBonus The amount of bonus actually sent for the block producer, returns 0 when the transfer is failed.\n * @return _bridgeOperatorBonus The amount of bonus actually sent for the bridge operator, returns 0 when the transfer is failed.\n *\n */\n function requestBonus(bool _forBlockProducer, bool _forBridgeOperator)\n external\n returns (\n bool _success,\n uint256 _blockProducerBonus,\n uint256 _bridgeOperatorBonus\n );\n\n /**\n * @dev Sets the bonus amount per block for block producer.\n *\n * Emits the event `BlockProducerBonusPerBlockUpdated`.\n *\n * Requirements:\n * - The method caller is admin.\n *\n */\n function setBlockProducerBonusPerBlock(uint256 _amount) external;\n\n /**\n * @dev Sets the bonus amount per block for bridge operator.\n *\n * Emits the event `BridgeOperatorBonusPerBlockUpdated`.\n *\n * Requirements:\n * - The method caller is admin.\n *\n */\n function setBridgeOperatorBonusPerBlock(uint256 _amount) external;\n}\n" + }, + "contracts/ronin/validator/storage-fragments/JailingStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../../interfaces/validator/info-fragments/IJailingInfo.sol\";\nimport \"./TimingStorage.sol\";\n\nabstract contract JailingStorage is IJailingInfo {\n /// @dev Mapping from consensus address => period number => block producer has no pending reward\n mapping(address => mapping(uint256 => bool)) internal _miningRewardDeprecatedAtPeriod;\n /// @dev Mapping from consensus address => period number => whether the block producer get cut off reward, due to bailout\n mapping(address => mapping(uint256 => bool)) internal _miningRewardBailoutCutOffAtPeriod;\n /// @dev Mapping from consensus address => period number => block operator has no pending reward\n mapping(address => mapping(uint256 => bool)) internal _bridgeRewardDeprecatedAtPeriod;\n /// @dev Mapping from consensus address => the last block that the validator is jailed\n mapping(address => uint256) internal _jailedUntil;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n /**\n * @inheritdoc IJailingInfo\n */\n function checkJailed(address _addr) external view override returns (bool) {\n return checkJailedAtBlock(_addr, block.number);\n }\n\n /**\n * @inheritdoc IJailingInfo\n */\n function getJailedTimeLeft(address _addr)\n external\n view\n override\n returns (\n bool isJailed_,\n uint256 blockLeft_,\n uint256 epochLeft_\n )\n {\n return getJailedTimeLeftAtBlock(_addr, block.number);\n }\n\n /**\n * @inheritdoc IJailingInfo\n */\n function checkJailedAtBlock(address _addr, uint256 _blockNum) public view override returns (bool) {\n return _jailedAtBlock(_addr, _blockNum);\n }\n\n /**\n * @inheritdoc IJailingInfo\n */\n function getJailedTimeLeftAtBlock(address _addr, uint256 _blockNum)\n public\n view\n override\n returns (\n bool isJailed_,\n uint256 blockLeft_,\n uint256 epochLeft_\n )\n {\n uint256 _jailedBlock = _jailedUntil[_addr];\n if (_jailedBlock < _blockNum) {\n return (false, 0, 0);\n }\n\n isJailed_ = true;\n blockLeft_ = _jailedBlock - _blockNum + 1;\n epochLeft_ = epochOf(_jailedBlock) - epochOf(_blockNum) + 1;\n }\n\n /**\n * @inheritdoc IJailingInfo\n */\n function checkManyJailed(address[] calldata _addrList) external view override returns (bool[] memory _result) {\n _result = new bool[](_addrList.length);\n for (uint256 _i; _i < _addrList.length; _i++) {\n _result[_i] = _jailed(_addrList[_i]);\n }\n }\n\n /**\n * @inheritdoc IJailingInfo\n */\n function checkMiningRewardDeprecated(address[] calldata _blockProducers)\n external\n view\n override\n returns (bool[] memory _result)\n {\n _result = new bool[](_blockProducers.length);\n uint256 _period = currentPeriod();\n for (uint256 _i; _i < _blockProducers.length; _i++) {\n _result[_i] = _miningRewardDeprecated(_blockProducers[_i], _period);\n }\n }\n\n /**\n * @inheritdoc IJailingInfo\n */\n function checkMiningRewardDeprecatedAtPeriod(address[] calldata _blockProducers, uint256 _period)\n external\n view\n override\n returns (bool[] memory _result)\n {\n _result = new bool[](_blockProducers.length);\n for (uint256 _i; _i < _blockProducers.length; _i++) {\n _result[_i] = _miningRewardDeprecated(_blockProducers[_i], _period);\n }\n }\n\n /**\n * @dev See `ITimingInfo-epochOf`\n */\n function epochOf(uint256 _block) public view virtual returns (uint256);\n\n /**\n * @dev See `ITimingInfo-currentPeriod`\n */\n function currentPeriod() public view virtual returns (uint256);\n\n /**\n * @dev Returns whether the reward of the validator is put in jail (cannot join the set of validators) during the current period.\n */\n function _jailed(address _validatorAddr) internal view returns (bool) {\n return _jailedAtBlock(_validatorAddr, block.number);\n }\n\n /**\n * @dev Returns whether the reward of the validator is put in jail (cannot join the set of validators) at a specific block.\n */\n function _jailedAtBlock(address _validatorAddr, uint256 _blockNum) internal view returns (bool) {\n return _blockNum <= _jailedUntil[_validatorAddr];\n }\n\n /**\n * @dev Returns whether the block producer has no pending reward in that period.\n */\n function _miningRewardDeprecated(address _validatorAddr, uint256 _period) internal view returns (bool) {\n return _miningRewardDeprecatedAtPeriod[_validatorAddr][_period];\n }\n\n /**\n * @dev Returns whether the bridge operator has no pending reward in the period.\n */\n function _bridgeRewardDeprecated(address _validatorAddr, uint256 _period) internal view returns (bool) {\n return _bridgeRewardDeprecatedAtPeriod[_validatorAddr][_period];\n }\n}\n" + }, + "contracts/ronin/validator/storage-fragments/TimingStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../../interfaces/validator/info-fragments/ITimingInfo.sol\";\n\nabstract contract TimingStorage is ITimingInfo {\n /// @dev Length of period in seconds\n uint256 internal constant _periodLength = 1 days;\n\n /// @dev The number of blocks in a epoch\n uint256 internal _numberOfBlocksInEpoch;\n /// @dev The last updated block\n uint256 internal _lastUpdatedBlock;\n /// @dev The last updated period\n uint256 internal _lastUpdatedPeriod;\n /// @dev The starting block of the last updated period\n uint256 internal _currentPeriodStartAtBlock;\n\n /// @dev Mapping from epoch index => period index\n mapping(uint256 => uint256) internal _periodOf;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[49] private ______gap;\n\n /**\n * @inheritdoc ITimingInfo\n */\n function getLastUpdatedBlock() external view override returns (uint256) {\n return _lastUpdatedBlock;\n }\n\n /**\n * @inheritdoc ITimingInfo\n */\n function epochOf(uint256 _block) public view virtual override returns (uint256) {\n return _block / _numberOfBlocksInEpoch + 1;\n }\n\n /**\n * @inheritdoc ITimingInfo\n */\n function tryGetPeriodOfEpoch(uint256 _epoch) external view returns (bool, uint256) {\n return (_epoch <= epochOf(block.number) || _periodOf[_epoch] > 0, _periodOf[_epoch]);\n }\n\n /**\n * @inheritdoc ITimingInfo\n */\n function isPeriodEnding() external view override returns (bool) {\n return _isPeriodEnding(_computePeriod(block.timestamp));\n }\n\n /**\n * @inheritdoc ITimingInfo\n */\n function epochEndingAt(uint256 _block) public view virtual override returns (bool) {\n return _block % _numberOfBlocksInEpoch == _numberOfBlocksInEpoch - 1;\n }\n\n /**\n * @inheritdoc ITimingInfo\n */\n function currentPeriod() public view virtual override returns (uint256) {\n return _lastUpdatedPeriod;\n }\n\n /**\n * @inheritdoc ITimingInfo\n */\n function currentPeriodStartAtBlock() public view override returns (uint256) {\n return _currentPeriodStartAtBlock;\n }\n\n /**\n * @inheritdoc ITimingInfo\n */\n function numberOfBlocksInEpoch() public view virtual override returns (uint256 _numberOfBlocks) {\n return _numberOfBlocksInEpoch;\n }\n\n /**\n * @dev See `ITimingInfo-isPeriodEnding`\n */\n function _isPeriodEnding(uint256 _newPeriod) public view virtual returns (bool) {\n return _newPeriod > _lastUpdatedPeriod;\n }\n\n /**\n * @dev Returns the calculated period.\n */\n function _computePeriod(uint256 _timestamp) internal pure returns (uint256) {\n return _timestamp / _periodLength;\n }\n}\n" + }, + "contracts/ronin/validator/storage-fragments/ValidatorInfoStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../../libraries/EnumFlags.sol\";\nimport \"../../../extensions/collections/HasRoninTrustedOrganizationContract.sol\";\nimport \"../../../interfaces/validator/info-fragments/IValidatorInfo.sol\";\n\nabstract contract ValidatorInfoStorage is IValidatorInfo, HasRoninTrustedOrganizationContract {\n using EnumFlags for EnumFlags.ValidatorFlag;\n\n /// @dev The maximum number of validator.\n uint256 internal _maxValidatorNumber;\n\n /// @dev The total of validators\n uint256 public validatorCount;\n /// @dev Mapping from validator index => validator address\n mapping(uint256 => address) internal _validators;\n /// @dev Mapping from address => flag indicating the validator ability: producing block, operating bridge\n mapping(address => EnumFlags.ValidatorFlag) internal _validatorMap;\n /// @dev The number of slot that is reserved for prioritized validators\n uint256 internal _maxPrioritizedValidatorNumber;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n /**\n * @inheritdoc IValidatorInfo\n */\n function getValidators() public view override returns (address[] memory _validatorList) {\n _validatorList = new address[](validatorCount);\n for (uint _i = 0; _i < _validatorList.length; _i++) {\n _validatorList[_i] = _validators[_i];\n }\n }\n\n /**\n * @inheritdoc IValidatorInfo\n */\n function isValidator(address _addr) public view override returns (bool) {\n return !_validatorMap[_addr].isNone();\n }\n\n /**\n * @inheritdoc IValidatorInfo\n */\n function getBlockProducers() public view override returns (address[] memory _result) {\n _result = new address[](validatorCount);\n uint256 _count = 0;\n for (uint _i = 0; _i < _result.length; _i++) {\n if (isBlockProducer(_validators[_i])) {\n _result[_count++] = _validators[_i];\n }\n }\n\n assembly {\n mstore(_result, _count)\n }\n }\n\n /**\n * @inheritdoc IValidatorInfo\n */\n function isBlockProducer(address _addr) public view override returns (bool) {\n return _validatorMap[_addr].hasFlag(EnumFlags.ValidatorFlag.BlockProducer);\n }\n\n /**\n * @inheritdoc IValidatorInfo\n */\n function totalBlockProducers() external view returns (uint256 _total) {\n for (uint _i = 0; _i < validatorCount; _i++) {\n if (isBlockProducer(_validators[_i])) {\n _total++;\n }\n }\n }\n\n /**\n * @inheritdoc IValidatorInfo\n */\n function getBridgeOperators() public view override returns (address[] memory _bridgeOperatorList) {\n _bridgeOperatorList = new address[](validatorCount);\n for (uint _i = 0; _i < _bridgeOperatorList.length; _i++) {\n _bridgeOperatorList[_i] = _bridgeOperatorOf(_validators[_i]);\n }\n }\n\n /**\n * @inheritdoc IValidatorInfo\n */\n function isBridgeOperator(address _bridgeOperatorAddr) external view override returns (bool _result) {\n for (uint _i = 0; _i < validatorCount; _i++) {\n if (_bridgeOperatorOf(_validators[_i]) == _bridgeOperatorAddr) {\n _result = true;\n break;\n }\n }\n }\n\n /**\n * @inheritdoc IValidatorInfo\n */\n function maxValidatorNumber() external view override returns (uint256 _maximumValidatorNumber) {\n return _maxValidatorNumber;\n }\n\n /**\n * @inheritdoc IValidatorInfo\n */\n function maxPrioritizedValidatorNumber() external view override returns (uint256 _maximumPrioritizedValidatorNumber) {\n return _maxPrioritizedValidatorNumber;\n }\n\n /**\n * Notice: A validator is always a bride operator\n *\n * @inheritdoc IValidatorInfo\n */\n function totalBridgeOperators() public view returns (uint256) {\n return validatorCount;\n }\n\n /**\n * @inheritdoc IValidatorInfo\n */\n function setMaxValidatorNumber(uint256 _max) external override onlyAdmin {\n _setMaxValidatorNumber(_max);\n }\n\n /**\n * @inheritdoc IValidatorInfo\n */\n function setMaxPrioritizedValidatorNumber(uint256 _number) external override onlyAdmin {\n _setMaxPrioritizedValidatorNumber(_number);\n }\n\n /**\n * @dev See `IValidatorInfo-setMaxValidatorNumber`\n */\n function _setMaxValidatorNumber(uint256 _number) internal {\n _maxValidatorNumber = _number;\n emit MaxValidatorNumberUpdated(_number);\n }\n\n /**\n * @dev See `IValidatorInfo-setMaxPrioritizedValidatorNumber`\n */\n function _setMaxPrioritizedValidatorNumber(uint256 _number) internal {\n require(\n _number <= _maxValidatorNumber,\n \"RoninValidatorSet: cannot set number of prioritized greater than number of max validators\"\n );\n\n _maxPrioritizedValidatorNumber = _number;\n emit MaxPrioritizedValidatorNumberUpdated(_number);\n }\n\n /**\n * @dev Returns the bridge operator of a consensus address.\n */\n function _bridgeOperatorOf(address _consensusAddr) internal view virtual returns (address);\n}\n" + }, + "contracts/extensions/collections/HasRoninTrustedOrganizationContract.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./HasProxyAdmin.sol\";\nimport \"../../interfaces/collections/IHasRoninTrustedOrganizationContract.sol\";\nimport \"../../interfaces/IRoninTrustedOrganization.sol\";\n\ncontract HasRoninTrustedOrganizationContract is IHasRoninTrustedOrganizationContract, HasProxyAdmin {\n IRoninTrustedOrganization internal _roninTrustedOrganizationContract;\n\n modifier onlyRoninTrustedOrganizationContract() {\n require(\n roninTrustedOrganizationContract() == msg.sender,\n \"HasRoninTrustedOrganizationContract: method caller must be ronin trusted organization contract\"\n );\n _;\n }\n\n /**\n * @inheritdoc IHasRoninTrustedOrganizationContract\n */\n function roninTrustedOrganizationContract() public view override returns (address) {\n return address(_roninTrustedOrganizationContract);\n }\n\n /**\n * @inheritdoc IHasRoninTrustedOrganizationContract\n */\n function setRoninTrustedOrganizationContract(address _addr) external virtual override onlyAdmin {\n require(_addr.code.length > 0, \"HasRoninTrustedOrganizationContract: set to non-contract\");\n _setRoninTrustedOrganizationContract(_addr);\n }\n\n /**\n * @dev Sets the ronin trusted organization contract.\n *\n * Emits the event `RoninTrustedOrganizationContractUpdated`.\n *\n */\n function _setRoninTrustedOrganizationContract(address _addr) internal {\n _roninTrustedOrganizationContract = IRoninTrustedOrganization(_addr);\n emit RoninTrustedOrganizationContractUpdated(_addr);\n }\n}\n" + }, + "contracts/interfaces/collections/IHasRoninTrustedOrganizationContract.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface IHasRoninTrustedOrganizationContract {\n /// @dev Emitted when the ronin trusted organization contract is updated.\n event RoninTrustedOrganizationContractUpdated(address);\n\n /**\n * @dev Returns the ronin trusted organization contract.\n */\n function roninTrustedOrganizationContract() external view returns (address);\n\n /**\n * @dev Sets the ronin trusted organization contract.\n *\n * Requirements:\n * - The method caller is admin.\n * - The new address is a contract.\n *\n * Emits the event `RoninTrustedOrganizationContractUpdated`.\n *\n */\n function setRoninTrustedOrganizationContract(address) external;\n}\n" + }, + "contracts/interfaces/IRoninTrustedOrganization.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"./IQuorum.sol\";\n\ninterface IRoninTrustedOrganization is IQuorum {\n struct TrustedOrganization {\n // Address of the validator that produces block, e.g. block.coinbase. This is so-called validator address.\n address consensusAddr;\n // Address to voting proposal\n address governor;\n // Address to voting bridge operators\n address bridgeVoter;\n // Its Weight\n uint256 weight;\n // The block that the organization was added\n uint256 addedBlock;\n }\n\n /// @dev Emitted when the trusted organization is added.\n event TrustedOrganizationsAdded(TrustedOrganization[] orgs);\n /// @dev Emitted when the trusted organization is updated.\n event TrustedOrganizationsUpdated(TrustedOrganization[] orgs);\n /// @dev Emitted when the trusted organization is removed.\n event TrustedOrganizationsRemoved(address[] orgs);\n\n /**\n * @dev Adds a list of addresses into the trusted organization.\n *\n * Requirements:\n * - The weights should larger than 0.\n * - The method caller is admin.\n * - The field `addedBlock` should be blank.\n *\n * Emits the event `TrustedOrganizationAdded` once an organization is added.\n *\n */\n function addTrustedOrganizations(TrustedOrganization[] calldata) external;\n\n /**\n * @dev Updates weights for a list of existent trusted organization.\n *\n * Requirements:\n * - The weights should larger than 0.\n * - The method caller is admin.\n *\n * Emits the `TrustedOrganizationUpdated` event.\n *\n */\n function updateTrustedOrganizations(TrustedOrganization[] calldata _list) external;\n\n /**\n * @dev Removes a list of addresses from the trusted organization.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the event `TrustedOrganizationRemoved` once an organization is removed.\n *\n * @param _consensusAddrs The list of consensus addresses linked to corresponding trusted organization that to be removed.\n */\n function removeTrustedOrganizations(address[] calldata _consensusAddrs) external;\n\n /**\n * @dev Returns total weights.\n */\n function totalWeights() external view returns (uint256);\n\n /**\n * @dev Returns the weight of a consensus.\n */\n function getConsensusWeight(address _consensusAddr) external view returns (uint256);\n\n /**\n * @dev Returns the weight of a governor.\n */\n function getGovernorWeight(address _governor) external view returns (uint256);\n\n /**\n * @dev Returns the weight of a bridge voter.\n */\n function getBridgeVoterWeight(address _addr) external view returns (uint256);\n\n /**\n * @dev Returns the weights of a list of consensus addresses.\n */\n function getConsensusWeights(address[] calldata _list) external view returns (uint256[] memory);\n\n /**\n * @dev Returns the weights of a list of governor addresses.\n */\n function getGovernorWeights(address[] calldata _list) external view returns (uint256[] memory);\n\n /**\n * @dev Returns the weights of a list of bridge voter addresses.\n */\n function getBridgeVoterWeights(address[] calldata _list) external view returns (uint256[] memory);\n\n /**\n * @dev Returns total weights of the consensus list.\n */\n function sumConsensusWeights(address[] calldata _list) external view returns (uint256 _res);\n\n /**\n * @dev Returns total weights of the governor list.\n */\n function sumGovernorWeights(address[] calldata _list) external view returns (uint256 _res);\n\n /**\n * @dev Returns total weights of the bridge voter list.\n */\n function sumBridgeVoterWeights(address[] calldata _list) external view returns (uint256 _res);\n\n /**\n * @dev Returns the trusted organization at `_index`.\n */\n function getTrustedOrganizationAt(uint256 _index) external view returns (TrustedOrganization memory);\n\n /**\n * @dev Returns the number of trusted organizations.\n */\n function countTrustedOrganizations() external view returns (uint256);\n\n /**\n * @dev Returns all of the trusted organizations.\n */\n function getAllTrustedOrganizations() external view returns (TrustedOrganization[] memory);\n\n /**\n * @dev Returns the trusted organization by consensus address.\n *\n * Reverts once the consensus address is non-existent.\n */\n function getTrustedOrganization(address _consensusAddr) external view returns (TrustedOrganization memory);\n}\n" + }, + "contracts/extensions/collections/HasStakingContract.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./HasProxyAdmin.sol\";\nimport \"../../interfaces/collections/IHasStakingContract.sol\";\nimport \"../../interfaces/staking/IStaking.sol\";\n\ncontract HasStakingContract is IHasStakingContract, HasProxyAdmin {\n IStaking internal _stakingContract;\n\n modifier onlyStakingContract() {\n require(stakingContract() == msg.sender, \"HasStakingContract: method caller must be staking contract\");\n _;\n }\n\n /**\n * @inheritdoc IHasStakingContract\n */\n function stakingContract() public view override returns (address) {\n return address(_stakingContract);\n }\n\n /**\n * @inheritdoc IHasStakingContract\n */\n function setStakingContract(address _addr) external override onlyAdmin {\n require(_addr.code.length > 0, \"HasStakingContract: set to non-contract\");\n _setStakingContract(_addr);\n }\n\n /**\n * @dev Sets the staking contract.\n *\n * Emits the event `StakingContractUpdated`.\n *\n */\n function _setStakingContract(address _addr) internal {\n _stakingContract = IStaking(_addr);\n emit StakingContractUpdated(_addr);\n }\n}\n" + }, + "contracts/extensions/consumers/PercentageConsumer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nabstract contract PercentageConsumer {\n uint256 internal constant _MAX_PERCENTAGE = 100_00;\n}\n" + }, + "contracts/interfaces/staking/IStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"./IBaseStaking.sol\";\nimport \"./ICandidateStaking.sol\";\nimport \"./IDelegatorStaking.sol\";\n\ninterface IStaking is IRewardPool, IBaseStaking, ICandidateStaking, IDelegatorStaking {\n /**\n * @dev Records the amount of rewards `_rewards` for the pools `_consensusAddrs`.\n *\n * Requirements:\n * - The method caller is validator contract.\n *\n * Emits the event `PoolsUpdated` once the contract recorded the rewards successfully.\n * Emits the event `PoolsUpdateFailed` once the input array lengths are not equal.\n * Emits the event `PoolsUpdateConflicted` when there are some pools which already updated in the period.\n *\n * Note: This method should be called once at the period ending.\n *\n */\n function recordRewards(\n address[] calldata _consensusAddrs,\n uint256[] calldata _rewards,\n uint256 _period\n ) external payable;\n\n /**\n * @dev Deducts from staking amount of the validator `_consensusAddr` for `_amount`.\n *\n * Requirements:\n * - The method caller is validator contract.\n *\n * Emits the event `Unstaked`.\n *\n */\n function deductStakingAmount(address _consensusAddr, uint256 _amount)\n external\n returns (uint256 _actualDeductingAmount);\n\n /**\n * @dev Returns the staking pool detail.\n */\n function getStakingPool(address)\n external\n view\n returns (\n address _admin,\n uint256 _stakingAmount,\n uint256 _stakingTotal\n );\n\n /**\n * @dev Returns the self-staking amounts of the pools.\n */\n function getManySelfStakings(address[] calldata) external view returns (uint256[] memory);\n}\n" + }, + "contracts/interfaces/collections/IHasStakingContract.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface IHasStakingContract {\n /// @dev Emitted when the staking contract is updated.\n event StakingContractUpdated(address);\n\n /**\n * @dev Returns the staking contract.\n */\n function stakingContract() external view returns (address);\n\n /**\n * @dev Sets the staking contract.\n *\n * Requirements:\n * - The method caller is admin.\n * - The new address is a contract.\n *\n * Emits the event `StakingContractUpdated`.\n *\n */\n function setStakingContract(address) external;\n}\n" + }, + "contracts/interfaces/staking/IBaseStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface IBaseStaking {\n struct PoolDetail {\n // Address of the pool i.e. consensus address of the validator\n address addr;\n // Pool admin address\n address admin;\n // Self-staking amount\n uint256 stakingAmount;\n // Total number of RON staking for the pool\n uint256 stakingTotal;\n // Mapping from delegator => delegating amount\n mapping(address => uint256) delegatingAmount;\n // Mapping from delegator => the last timestamp that delegator staked\n mapping(address => uint256) lastDelegatingTimestamp;\n }\n\n /// @dev Emitted when the minium number of seconds to undelegate is updated.\n event CooldownSecsToUndelegateUpdated(uint256 minSecs);\n /// @dev Emitted when the number of seconds that a candidate must wait to be revoked.\n event WaitingSecsToRevokeUpdated(uint256 secs);\n\n /**\n * @dev Returns whether the `_poolAdminAddr` is currently active.\n */\n function isActivePoolAdmin(address _poolAdminAddr) external view returns (bool);\n\n /**\n * @dev Returns the consensus address corresponding to the pool admin.\n */\n function getPoolAddressOf(address _poolAdminAddr) external view returns (address);\n\n /**\n * @dev Returns The cooldown time in seconds to undelegate from the last timestamp (s)he delegated.\n */\n function cooldownSecsToUndelegate() external view returns (uint256);\n\n /**\n * @dev Returns the number of seconds that a candidate must wait for the renounce request gets affected.\n */\n function waitingSecsToRevoke() external view returns (uint256);\n\n /**\n * @dev Sets the cooldown time in seconds to undelegate from the last timestamp (s)he delegated.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the event `CooldownSecsToUndelegateUpdated`.\n *\n */\n function setCooldownSecsToUndelegate(uint256 _cooldownSecs) external;\n\n /**\n * @dev Sets the number of seconds that a candidate must wait to be revoked.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the event `WaitingSecsToRevokeUpdated`.\n *\n */\n function setWaitingSecsToRevoke(uint256 _secs) external;\n}\n" + }, + "contracts/interfaces/staking/ICandidateStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"./IRewardPool.sol\";\n\ninterface ICandidateStaking is IRewardPool {\n /// @dev Emitted when the minimum staking amount for being a validator is updated.\n event MinValidatorStakingAmountUpdated(uint256 threshold);\n\n /// @dev Emitted when the pool admin staked for themself.\n event Staked(address indexed consensuAddr, uint256 amount);\n /// @dev Emitted when the pool admin unstaked the amount of RON from themself.\n event Unstaked(address indexed consensuAddr, uint256 amount);\n\n /// @dev Emitted when the validator pool is approved.\n event PoolApproved(address indexed validator, address indexed admin);\n /// @dev Emitted when the validator pool is deprecated.\n event PoolsDeprecated(address[] validator);\n /// @dev Emitted when the staking amount transfer failed.\n event StakingAmountTransferFailed(\n address indexed validator,\n address indexed admin,\n uint256 amount,\n uint256 contractBalance\n );\n /// @dev Emitted when the staking amount deducted failed, e.g. when the validator gets slashed.\n event StakingAmountDeductFailed(\n address indexed validator,\n address indexed recipient,\n uint256 amount,\n uint256 contractBalance\n );\n\n /**\n * @dev Returns the minimum threshold for being a validator candidate.\n */\n function minValidatorStakingAmount() external view returns (uint256);\n\n /**\n * @dev Sets the minimum threshold for being a validator candidate.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the `MinValidatorStakingAmountUpdated` event.\n *\n */\n function setMinValidatorStakingAmount(uint256) external;\n\n /**\n * @dev Proposes a candidate to become a validator.\n *\n * Requirements:\n * - The method caller is able to receive RON.\n * - The treasury is able to receive RON.\n * - The amount is larger than or equal to the minimum validator staking amount `minValidatorStakingAmount()`.\n *\n * Emits the event `PoolApproved`.\n *\n * @param _candidateAdmin the candidate admin will be stored in the validator contract, used for calling function that affects\n * to its candidate, e.g. scheduling maintenance.\n *\n */\n function applyValidatorCandidate(\n address _candidateAdmin,\n address _consensusAddr,\n address payable _treasuryAddr,\n address _bridgeOperatorAddr,\n uint256 _commissionRate\n ) external payable;\n\n /**\n * @dev Deprecates the pool.\n * - Deduct self-staking amount of the pool admin to zero.\n * - Transfer the deducted amount to the pool admin.\n * - Deactivate the pool admin address in the mapping of active pool admins\n *\n * Requirements:\n * - The method caller is validator contract.\n *\n * Emits the event `PoolsDeprecated` and `Unstaked` events.\n * Emits the event `StakingAmountTransferFailed` if the contract cannot transfer RON back to the pool admin.\n *\n */\n function deprecatePools(address[] calldata _pools) external;\n\n /**\n * @dev Self-delegates to the validator candidate `_consensusAddr`.\n *\n * Requirements:\n * - The consensus address is a validator candidate.\n * - The method caller is the pool admin.\n * - The `msg.value` is larger than 0.\n *\n * Emits the event `Staked`.\n *\n */\n function stake(address _consensusAddr) external payable;\n\n /**\n * @dev Unstakes from the validator candidate `_consensusAddr` for `_amount`.\n *\n * Requirements:\n * - The consensus address is a validator candidate.\n * - The method caller is the pool admin.\n *\n * Emits the event `Unstaked`.\n *\n */\n function unstake(address _consensusAddr, uint256 _amount) external;\n\n /**\n * @dev Pool admin requests update validator commission rate. The request will be forwarded to the candidate manager\n * contract, and the value is getting updated in {ICandidateManager-execRequestUpdateCommissionRate}.\n *\n * Requirements:\n * - The consensus address is a validator candidate.\n * - The method caller is the pool admin.\n * - The `_effectiveDaysOnwards` must be equal to or larger than the {CandidateManager-_minEffectiveDaysOnwards}.\n * - The `_rate` must be in range of [0_00; 100_00].\n *\n * Emits the event `CommissionRateUpdated`.\n *\n */\n function requestUpdateCommissionRate(\n address _consensusAddr,\n uint256 _effectiveDaysOnwards,\n uint256 _commissionRate\n ) external;\n\n /**\n * @dev Renounces being a validator candidate and takes back the delegating/staking amount.\n *\n * Requirements:\n * - The consensus address is a validator candidate.\n * - The method caller is the pool admin.\n *\n */\n function requestRenounce(address _consensusAddr) external;\n}\n" + }, + "contracts/interfaces/staking/IDelegatorStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"./IRewardPool.sol\";\n\ninterface IDelegatorStaking is IRewardPool {\n /// @dev Emitted when the delegator staked for a validator candidate.\n event Delegated(address indexed delegator, address indexed consensuAddr, uint256 amount);\n /// @dev Emitted when the delegator unstaked from a validator candidate.\n event Undelegated(address indexed delegator, address indexed consensuAddr, uint256 amount);\n\n /**\n * @dev Stakes for a validator candidate `_consensusAddr`.\n *\n * Requirements:\n * - The consensus address is a validator candidate.\n * - The method caller is not the pool admin.\n *\n * Emits the `Delegated` event.\n *\n */\n function delegate(address _consensusAddr) external payable;\n\n /**\n * @dev Unstakes from a validator candidate `_consensusAddr` for `_amount`.\n *\n * Requirements:\n * - The method caller is not the pool admin.\n *\n * Emits the `Undelegated` event.\n *\n */\n function undelegate(address _consensusAddr, uint256 _amount) external;\n\n /**\n * @dev Bulk unstakes from a list of candidates.\n *\n * Requirements:\n * - The method caller is not the pool admin.\n *\n * Emits the events `Undelegated`.\n *\n */\n function bulkUndelegate(address[] calldata _consensusAddrs, uint256[] calldata _amounts) external;\n\n /**\n * @dev Unstakes an amount of RON from the `_consensusAddrSrc` and stake for `_consensusAddrDst`.\n *\n * Requirements:\n * - The method caller is not the pool admin.\n * - The consensus address `_consensusAddrDst` is a validator candidate.\n *\n * Emits the `Undelegated` event and the `Delegated` event.\n *\n */\n function redelegate(\n address _consensusAddrSrc,\n address _consensusAddrDst,\n uint256 _amount\n ) external;\n\n /**\n * @dev Returns the claimable reward of the user `_user`.\n */\n function getRewards(address _user, address[] calldata _poolAddrList)\n external\n view\n returns (uint256[] memory _rewards);\n\n /**\n * @dev Claims the reward of method caller.\n *\n * Emits the `RewardClaimed` event.\n *\n */\n function claimRewards(address[] calldata _consensusAddrList) external returns (uint256 _amount);\n\n /**\n * @dev Claims the rewards and delegates them to the consensus address.\n *\n * Requirements:\n * - The method caller is not the pool admin.\n * - The consensus address `_consensusAddrDst` is a validator candidate.\n *\n * Emits the `RewardClaimed` event and the `Delegated` event.\n *\n */\n function delegateRewards(address[] calldata _consensusAddrList, address _consensusAddrDst)\n external\n returns (uint256 _amount);\n}\n" + }, + "contracts/interfaces/staking/IRewardPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../interfaces/consumers/PeriodWrapperConsumer.sol\";\n\ninterface IRewardPool is PeriodWrapperConsumer {\n struct UserRewardFields {\n // Recorded reward amount.\n uint256 debited;\n // The last accumulated of the amount rewards per share (one unit staking) that the info updated.\n uint256 aRps;\n // Min staking amount in the period.\n uint256 minAmount;\n // Last period number that the info updated.\n uint256 lastPeriod;\n }\n\n struct PoolFields {\n // Accumulated of the amount rewards per share (one unit staking).\n uint256 aRps;\n // The staking total to share reward of the current period.\n PeriodWrapper shares;\n }\n\n /// @dev Emitted when the fields to calculate pending reward for the user is updated.\n event UserRewardUpdated(address indexed poolAddr, address indexed user, uint256 debited);\n /// @dev Emitted when the user claimed their reward\n event RewardClaimed(address indexed poolAddr, address indexed user, uint256 amount);\n\n /// @dev Emitted when the pool shares are updated\n event PoolSharesUpdated(uint256 indexed period, address indexed poolAddr, uint256 shares);\n /// @dev Emitted when the pools are updated\n event PoolsUpdated(uint256 indexed period, address[] poolAddrs, uint256[] aRps, uint256[] shares);\n /// @dev Emitted when the contract fails when updating the pools\n event PoolsUpdateFailed(uint256 indexed period, address[] poolAddrs, uint256[] rewards);\n /// @dev Emitted when the contract fails when updating the pools that already set\n event PoolsUpdateConflicted(uint256 indexed period, address[] poolAddrs);\n\n /**\n * @dev Returns the reward amount that user claimable.\n */\n function getReward(address _poolAddr, address _user) external view returns (uint256);\n\n /**\n * @dev Returns the staking amount of an user.\n */\n function getStakingAmount(address _poolAddr, address _user) external view returns (uint256);\n\n /**\n * @dev Returns the staking amounts of the users.\n */\n function getManyStakingAmounts(address[] calldata _poolAddrs, address[] calldata _userList)\n external\n view\n returns (uint256[] memory);\n\n /**\n * @dev Returns the total staking amount of all users for a pool.\n */\n function getStakingTotal(address _poolAddr) external view returns (uint256);\n\n /**\n * @dev Returns the total staking amounts of all users for the pools `_poolAddrs`.\n */\n function getManyStakingTotals(address[] calldata _poolAddrs) external view returns (uint256[] memory);\n}\n" + }, + "contracts/interfaces/consumers/PeriodWrapperConsumer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface PeriodWrapperConsumer {\n struct PeriodWrapper {\n // Inner value.\n uint256 inner;\n // Last period number that the info updated.\n uint256 lastPeriod;\n }\n}\n" + }, + "contracts/mocks/validator/MockValidatorSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../interfaces/validator/IRoninValidatorSet.sol\";\nimport \"../../ronin/validator/CandidateManager.sol\";\n\ncontract MockValidatorSet is IRoninValidatorSet, CandidateManager {\n address public stakingVestingContract;\n address public slashIndicatorContract;\n\n uint256 internal _lastUpdatedPeriod;\n uint256 internal _numberOfBlocksInEpoch;\n /// @dev Mapping from period number => slashed\n mapping(uint256 => bool) internal _periodSlashed;\n\n constructor(\n address __stakingContract,\n address _slashIndicatorContract,\n address _stakingVestingContract,\n uint256 __maxValidatorCandidate,\n uint256 __numberOfBlocksInEpoch,\n uint256 __minEffectiveDaysOnwards\n ) {\n _setStakingContract(__stakingContract);\n _setMaxValidatorCandidate(__maxValidatorCandidate);\n slashIndicatorContract = _slashIndicatorContract;\n stakingVestingContract = _stakingVestingContract;\n _numberOfBlocksInEpoch = __numberOfBlocksInEpoch;\n _minEffectiveDaysOnwards = __minEffectiveDaysOnwards;\n }\n\n function submitBlockReward() external payable override {}\n\n function wrapUpEpoch() external payable override {\n _syncCandidateSet();\n _lastUpdatedPeriod = currentPeriod();\n }\n\n function getLastUpdatedBlock() external view override returns (uint256) {}\n\n function checkManyJailed(address[] calldata) external view override returns (bool[] memory) {}\n\n function checkMiningRewardDeprecatedAtPeriod(address[] calldata, uint256 _period)\n external\n view\n override\n returns (bool[] memory)\n {}\n\n function checkMiningRewardDeprecated(address[] calldata) external view override returns (bool[] memory) {}\n\n function epochOf(uint256 _block) external view override returns (uint256) {}\n\n function getValidators() external view override returns (address[] memory) {}\n\n function epochEndingAt(uint256 _block) external view override returns (bool) {}\n\n function execSlash(\n address _validatorAddr,\n uint256 _newJailedUntil,\n uint256 _slashAmount\n ) external override {}\n\n function execBailOut(address, uint256) external override {}\n\n function setMaxValidatorNumber(uint256 _maxValidatorNumber) external override {}\n\n function setMaxPrioritizedValidatorNumber(uint256 _maxPrioritizedValidatorNumber) external override {}\n\n function maxValidatorNumber() external view override returns (uint256 _maximumValidatorNumber) {}\n\n function maxPrioritizedValidatorNumber()\n external\n view\n override\n returns (uint256 _maximumPrioritizedValidatorNumber)\n {}\n\n function isValidator(address) external pure override returns (bool) {\n return true;\n }\n\n function numberOfBlocksInEpoch() public view override returns (uint256) {\n return _numberOfBlocksInEpoch;\n }\n\n function getBridgeOperators() external view override returns (address[] memory) {}\n\n function isBridgeOperator(address) external pure override returns (bool) {\n return true;\n }\n\n function totalBridgeOperators() external view override returns (uint256) {}\n\n function getBlockProducers() external view override returns (address[] memory) {}\n\n function isBlockProducer(address) external pure override returns (bool) {\n return true;\n }\n\n function totalBlockProducers() external view override returns (uint256) {}\n\n function tryGetPeriodOfEpoch(uint256) external view returns (bool, uint256) {}\n\n function isPeriodEnding() public view virtual returns (bool) {\n return currentPeriod() > _lastUpdatedPeriod;\n }\n\n function currentPeriod() public view override returns (uint256) {\n return block.timestamp / 86400;\n }\n\n function checkJailed(address) external view override returns (bool) {}\n\n function getJailedTimeLeft(address)\n external\n view\n override\n returns (\n bool,\n uint256,\n uint256\n )\n {}\n\n function currentPeriodStartAtBlock() external view override returns (uint256) {}\n\n function checkJailedAtBlock(address _addr, uint256 _blockNum) external view override returns (bool) {}\n\n function getJailedTimeLeftAtBlock(address _addr, uint256 _blockNum)\n external\n view\n override\n returns (\n bool isJailed_,\n uint256 blockLeft_,\n uint256 epochLeft_\n )\n {}\n\n function totalDeprecatedReward() external view override returns (uint256) {}\n}\n" + }, + "contracts/ronin/staking/Staking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport \"../../interfaces/staking/IStaking.sol\";\nimport \"../../interfaces/validator/IRoninValidatorSet.sol\";\nimport \"./CandidateStaking.sol\";\nimport \"./DelegatorStaking.sol\";\n\ncontract Staking is IStaking, CandidateStaking, DelegatorStaking, Initializable {\n constructor() {\n _disableInitializers();\n }\n\n receive() external payable onlyValidatorContract {}\n\n fallback() external payable onlyValidatorContract {}\n\n /**\n * @dev Initializes the contract storage.\n */\n function initialize(\n address __validatorContract,\n uint256 __minValidatorStakingAmount,\n uint256 __cooldownSecsToUndelegate,\n uint256 __waitingSecsToRevoke\n ) external initializer {\n _setValidatorContract(__validatorContract);\n _setMinValidatorStakingAmount(__minValidatorStakingAmount);\n _setCooldownSecsToUndelegate(__cooldownSecsToUndelegate);\n _setWaitingSecsToRevoke(__waitingSecsToRevoke);\n }\n\n /**\n * @inheritdoc IStaking\n */\n function getStakingPool(address _poolAddr)\n external\n view\n poolExists(_poolAddr)\n returns (\n address _admin,\n uint256 _stakingAmount,\n uint256 _stakingTotal\n )\n {\n PoolDetail storage _pool = _stakingPool[_poolAddr];\n return (_pool.admin, _pool.stakingAmount, _pool.stakingTotal);\n }\n\n /**\n * @inheritdoc IStaking\n */\n function getManySelfStakings(address[] calldata _pools) external view returns (uint256[] memory _selfStakings) {\n _selfStakings = new uint256[](_pools.length);\n for (uint _i = 0; _i < _pools.length; _i++) {\n _selfStakings[_i] = _stakingPool[_pools[_i]].stakingAmount;\n }\n }\n\n /**\n * @inheritdoc IStaking\n */\n function recordRewards(\n address[] calldata _consensusAddrs,\n uint256[] calldata _rewards,\n uint256 _period\n ) external payable onlyValidatorContract {\n _recordRewards(_consensusAddrs, _rewards, _period);\n }\n\n /**\n * @inheritdoc IStaking\n */\n function deductStakingAmount(address _consensusAddr, uint256 _amount)\n external\n onlyValidatorContract\n returns (uint256 _actualDeductingAmount)\n {\n _actualDeductingAmount = _deductStakingAmount(_stakingPool[_consensusAddr], _amount);\n address payable _recipientAddr = payable(validatorContract());\n if (!_unsafeSendRON(_recipientAddr, _actualDeductingAmount)) {\n emit StakingAmountDeductFailed(_consensusAddr, _recipientAddr, _actualDeductingAmount, address(this).balance);\n }\n }\n\n /**\n * @inheritdoc RewardCalculation\n */\n function _currentPeriod() internal view virtual override returns (uint256) {\n return _validatorContract.currentPeriod();\n }\n\n /**\n * @inheritdoc CandidateStaking\n */\n function _deductStakingAmount(PoolDetail storage _pool, uint256 _amount)\n internal\n override\n returns (uint256 _actualDeductingAmount)\n {\n _actualDeductingAmount = Math.min(_pool.stakingAmount, _amount);\n\n _pool.stakingAmount -= _actualDeductingAmount;\n _changeDelegatingAmount(_pool, _pool.admin, _pool.stakingAmount, _pool.stakingTotal - _actualDeductingAmount);\n emit Unstaked(_pool.addr, _actualDeductingAmount);\n }\n}\n" + }, + "contracts/ronin/staking/CandidateStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../libraries/AddressArrayUtils.sol\";\nimport \"../../interfaces/staking/ICandidateStaking.sol\";\nimport \"./BaseStaking.sol\";\n\nabstract contract CandidateStaking is BaseStaking, ICandidateStaking {\n /// @dev The minimum threshold for being a validator candidate.\n uint256 internal _minValidatorStakingAmount;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n /**\n * @inheritdoc ICandidateStaking\n */\n function minValidatorStakingAmount() public view override returns (uint256) {\n return _minValidatorStakingAmount;\n }\n\n /**\n * @inheritdoc ICandidateStaking\n */\n function setMinValidatorStakingAmount(uint256 _threshold) external override onlyAdmin {\n _setMinValidatorStakingAmount(_threshold);\n }\n\n /**\n * @inheritdoc ICandidateStaking\n */\n function applyValidatorCandidate(\n address _candidateAdmin,\n address _consensusAddr,\n address payable _treasuryAddr,\n address _bridgeOperatorAddr,\n uint256 _commissionRate\n ) external payable override nonReentrant {\n require(!isActivePoolAdmin(msg.sender), \"CandidateStaking: pool admin is active\");\n\n uint256 _amount = msg.value;\n address payable _poolAdmin = payable(msg.sender);\n _applyValidatorCandidate(\n _poolAdmin,\n _candidateAdmin,\n _consensusAddr,\n _treasuryAddr,\n _bridgeOperatorAddr,\n _commissionRate,\n _amount\n );\n\n PoolDetail storage _pool = _stakingPool[_consensusAddr];\n _pool.admin = _poolAdmin;\n _pool.addr = _consensusAddr;\n _activePoolAdminMapping[_poolAdmin] = _consensusAddr;\n\n _stake(_stakingPool[_consensusAddr], _poolAdmin, _amount);\n emit PoolApproved(_consensusAddr, _poolAdmin);\n }\n\n /**\n * @inheritdoc ICandidateStaking\n */\n function requestUpdateCommissionRate(\n address _consensusAddr,\n uint256 _effectiveDaysOnwards,\n uint256 _commissionRate\n ) external override poolExists(_consensusAddr) onlyPoolAdmin(_stakingPool[_consensusAddr], msg.sender) {\n _validatorContract.execRequestUpdateCommissionRate(_consensusAddr, _effectiveDaysOnwards, _commissionRate);\n }\n\n /**\n * @inheritdoc ICandidateStaking\n */\n function deprecatePools(address[] calldata _pools) external override onlyValidatorContract {\n if (_pools.length == 0) {\n return;\n }\n\n uint256 _amount;\n for (uint _i = 0; _i < _pools.length; _i++) {\n PoolDetail storage _pool = _stakingPool[_pools[_i]];\n // Deactivate the pool admin in the active mapping.\n delete _activePoolAdminMapping[_pool.admin];\n\n // Deduct and transfer the self staking amount to the pool admin.\n _amount = _pool.stakingAmount;\n if (_amount > 0) {\n _deductStakingAmount(_pool, _amount);\n if (!_unsafeSendRON(payable(_pool.admin), _amount)) {\n emit StakingAmountTransferFailed(_pool.addr, _pool.admin, _amount, address(this).balance);\n }\n }\n }\n\n emit PoolsDeprecated(_pools);\n }\n\n /**\n * @inheritdoc ICandidateStaking\n */\n function stake(address _consensusAddr) external payable override noEmptyValue poolExists(_consensusAddr) {\n _stake(_stakingPool[_consensusAddr], msg.sender, msg.value);\n }\n\n /**\n * @inheritdoc ICandidateStaking\n */\n function unstake(address _consensusAddr, uint256 _amount) external override nonReentrant poolExists(_consensusAddr) {\n require(_amount > 0, \"CandidateStaking: invalid amount\");\n address _delegator = msg.sender;\n PoolDetail storage _pool = _stakingPool[_consensusAddr];\n uint256 _remainAmount = _pool.stakingAmount - _amount;\n require(_remainAmount >= _minValidatorStakingAmount, \"CandidateStaking: invalid staking amount left\");\n\n _unstake(_pool, _delegator, _amount);\n require(_sendRON(payable(_delegator), _amount), \"CandidateStaking: could not transfer RON\");\n }\n\n /**\n * @inheritdoc ICandidateStaking\n */\n function requestRenounce(address _consensusAddr)\n external\n override\n poolExists(_consensusAddr)\n onlyPoolAdmin(_stakingPool[_consensusAddr], msg.sender)\n {\n _validatorContract.requestRevokeCandidate(_consensusAddr, _waitingSecsToRevoke);\n }\n\n /**\n * @dev See `ICandidateStaking-applyValidatorCandidate`\n */\n function _applyValidatorCandidate(\n address payable _poolAdmin,\n address _candidateAdmin,\n address _consensusAddr,\n address payable _treasuryAddr,\n address _bridgeOperatorAddr,\n uint256 _commissionRate,\n uint256 _amount\n ) internal {\n require(_sendRON(_poolAdmin, 0), \"CandidateStaking: pool admin cannot receive RON\");\n require(_sendRON(_treasuryAddr, 0), \"CandidateStaking: treasury cannot receive RON\");\n require(_amount >= _minValidatorStakingAmount, \"CandidateStaking: insufficient amount\");\n\n require(\n _poolAdmin == _candidateAdmin && _candidateAdmin == _treasuryAddr,\n \"CandidateStaking: three interaction addresses must be of the same\"\n );\n\n address[] memory _diffAddrs = new address[](3);\n _diffAddrs[0] = _poolAdmin;\n _diffAddrs[1] = _consensusAddr;\n _diffAddrs[2] = _bridgeOperatorAddr;\n require(\n !AddressArrayUtils.hasDuplicate(_diffAddrs),\n \"CandidateStaking: three operation addresses must be distinct\"\n );\n\n _validatorContract.grantValidatorCandidate(\n _candidateAdmin,\n _consensusAddr,\n _treasuryAddr,\n _bridgeOperatorAddr,\n _commissionRate\n );\n }\n\n /**\n * @dev See `ICandidateStaking-stake`\n */\n function _stake(\n PoolDetail storage _pool,\n address _requester,\n uint256 _amount\n ) internal onlyPoolAdmin(_pool, _requester) {\n _pool.stakingAmount += _amount;\n _changeDelegatingAmount(_pool, _requester, _pool.stakingAmount, _pool.stakingTotal + _amount);\n _pool.lastDelegatingTimestamp[_requester] = block.timestamp;\n emit Staked(_pool.addr, _amount);\n }\n\n /**\n * @dev See `ICandidateStaking-unstake`\n */\n function _unstake(\n PoolDetail storage _pool,\n address _requester,\n uint256 _amount\n ) internal onlyPoolAdmin(_pool, _requester) {\n require(_amount <= _pool.stakingAmount, \"CandidateStaking: insufficient staking amount\");\n require(\n _pool.lastDelegatingTimestamp[_requester] + _cooldownSecsToUndelegate <= block.timestamp,\n \"CandidateStaking: unstake too early\"\n );\n\n _pool.stakingAmount -= _amount;\n _changeDelegatingAmount(_pool, _requester, _pool.stakingAmount, _pool.stakingTotal - _amount);\n emit Unstaked(_pool.addr, _amount);\n }\n\n /**\n * @dev Deducts from staking amount of the validator `_consensusAddr` for `_amount`.\n *\n * Emits the event `Unstaked`.\n *\n * @return The actual deducted amount\n */\n function _deductStakingAmount(PoolDetail storage _pool, uint256 _amount) internal virtual returns (uint256);\n\n /**\n * @dev Sets the minimum threshold for being a validator candidate.\n *\n * Emits the `MinValidatorStakingAmountUpdated` event.\n *\n */\n function _setMinValidatorStakingAmount(uint256 _threshold) internal {\n _minValidatorStakingAmount = _threshold;\n emit MinValidatorStakingAmountUpdated(_threshold);\n }\n}\n" + }, + "contracts/ronin/staking/DelegatorStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../interfaces/staking/IDelegatorStaking.sol\";\nimport \"./BaseStaking.sol\";\n\nabstract contract DelegatorStaking is BaseStaking, IDelegatorStaking {\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n /**\n * @inheritdoc IDelegatorStaking\n */\n function delegate(address _consensusAddr) external payable noEmptyValue poolExists(_consensusAddr) {\n require(!isActivePoolAdmin(msg.sender), \"DelegatorStaking: admin of an active pool cannot delegate\");\n _delegate(_stakingPool[_consensusAddr], msg.sender, msg.value);\n }\n\n /**\n * @inheritdoc IDelegatorStaking\n */\n function undelegate(address _consensusAddr, uint256 _amount) external nonReentrant {\n address payable _delegator = payable(msg.sender);\n _undelegate(_stakingPool[_consensusAddr], _delegator, _amount);\n require(_sendRON(_delegator, _amount), \"DelegatorStaking: could not transfer RON\");\n }\n\n /**\n * @inheritdoc IDelegatorStaking\n */\n function bulkUndelegate(address[] calldata _consensusAddrs, uint256[] calldata _amounts) external nonReentrant {\n require(\n _consensusAddrs.length > 0 && _consensusAddrs.length == _amounts.length,\n \"DelegatorStaking: invalid array length\"\n );\n\n address payable _delegator = payable(msg.sender);\n uint256 _total;\n\n for (uint _i = 0; _i < _consensusAddrs.length; _i++) {\n _total += _amounts[_i];\n _undelegate(_stakingPool[_consensusAddrs[_i]], _delegator, _amounts[_i]);\n }\n\n require(_sendRON(_delegator, _total), \"DelegatorStaking: could not transfer RON\");\n }\n\n /**\n * @inheritdoc IDelegatorStaking\n */\n function redelegate(\n address _consensusAddrSrc,\n address _consensusAddrDst,\n uint256 _amount\n ) external nonReentrant poolExists(_consensusAddrDst) {\n address _delegator = msg.sender;\n _undelegate(_stakingPool[_consensusAddrSrc], _delegator, _amount);\n _delegate(_stakingPool[_consensusAddrDst], _delegator, _amount);\n }\n\n /**\n * @inheritdoc IDelegatorStaking\n */\n function claimRewards(address[] calldata _consensusAddrList)\n external\n override\n nonReentrant\n returns (uint256 _amount)\n {\n _amount = _claimRewards(msg.sender, _consensusAddrList);\n _transferRON(payable(msg.sender), _amount);\n }\n\n /**\n * @inheritdoc IDelegatorStaking\n */\n function delegateRewards(address[] calldata _consensusAddrList, address _consensusAddrDst)\n external\n override\n nonReentrant\n poolExists(_consensusAddrDst)\n returns (uint256 _amount)\n {\n return _delegateRewards(msg.sender, _consensusAddrList, _consensusAddrDst);\n }\n\n /**\n * @inheritdoc IDelegatorStaking\n */\n function getRewards(address _user, address[] calldata _poolAddrList)\n external\n view\n returns (uint256[] memory _rewards)\n {\n address _consensusAddr;\n uint256 _period = _validatorContract.currentPeriod();\n _rewards = new uint256[](_poolAddrList.length);\n\n for (uint256 _i = 0; _i < _poolAddrList.length; _i++) {\n _consensusAddr = _poolAddrList[_i];\n _rewards[_i] = _getReward(_consensusAddr, _user, _period, getStakingAmount(_consensusAddr, _user));\n }\n }\n\n /**\n * @dev Delegates from a validator address.\n *\n * Requirements:\n * - The delegator is not the pool admin.\n *\n * Emits the `Delegated` event.\n *\n * Note: This function does not verify the `msg.value` with the amount.\n *\n */\n function _delegate(\n PoolDetail storage _pool,\n address _delegator,\n uint256 _amount\n ) internal notPoolAdmin(_pool, _delegator) {\n _changeDelegatingAmount(\n _pool,\n _delegator,\n _pool.delegatingAmount[_delegator] + _amount,\n _pool.stakingTotal + _amount\n );\n _pool.lastDelegatingTimestamp[_delegator] = block.timestamp;\n emit Delegated(_delegator, _pool.addr, _amount);\n }\n\n /**\n * @dev Undelegates from a validator address.\n *\n * Requirements:\n * - The delegator is not the pool admin.\n * - The amount is larger than 0.\n * - The delegating amount is larger than or equal to the undelegating amount.\n *\n * Emits the `Undelegated` event.\n *\n * Note: Consider transferring back the amount of RON after calling this function.\n *\n */\n function _undelegate(\n PoolDetail storage _pool,\n address _delegator,\n uint256 _amount\n ) private notPoolAdmin(_pool, _delegator) {\n require(_amount > 0, \"DelegatorStaking: invalid amount\");\n require(_pool.delegatingAmount[_delegator] >= _amount, \"DelegatorStaking: insufficient amount to undelegate\");\n require(\n _pool.lastDelegatingTimestamp[_delegator] + _cooldownSecsToUndelegate < block.timestamp,\n \"DelegatorStaking: undelegate too early\"\n );\n _changeDelegatingAmount(\n _pool,\n _delegator,\n _pool.delegatingAmount[_delegator] - _amount,\n _pool.stakingTotal - _amount\n );\n emit Undelegated(_delegator, _pool.addr, _amount);\n }\n\n /**\n * @dev Claims rewards from the pools `_poolAddrList`.\n * Note: This function does not transfer reward to user.\n */\n function _claimRewards(address _user, address[] calldata _poolAddrList) internal returns (uint256 _amount) {\n for (uint256 _i = 0; _i < _poolAddrList.length; _i++) {\n _amount += _claimReward(_poolAddrList[_i], _user);\n }\n }\n\n /**\n * @dev Claims the rewards and delegates them to the consensus address.\n */\n function _delegateRewards(\n address _user,\n address[] calldata _poolAddrList,\n address _poolAddrDst\n ) internal returns (uint256 _amount) {\n _amount = _claimRewards(_user, _poolAddrList);\n _delegate(_stakingPool[_poolAddrDst], _user, _amount);\n }\n}\n" + }, + "contracts/libraries/AddressArrayUtils.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\n\npragma solidity ^0.8.0;\n\nlibrary AddressArrayUtils {\n /**\n * Returns whether or not there's a duplicate. Runs in O(n^2).\n * @param A Array to search\n * @return Returns true if duplicate, false otherwise\n */\n function hasDuplicate(address[] memory A) internal pure returns (bool) {\n if (A.length == 0) {\n return false;\n }\n for (uint256 i = 0; i < A.length - 1; i++) {\n for (uint256 j = i + 1; j < A.length; j++) {\n if (A[i] == A[j]) {\n return true;\n }\n }\n }\n return false;\n }\n}\n" + }, + "contracts/ronin/staking/BaseStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport \"../../extensions/RONTransferHelper.sol\";\nimport \"../../extensions/collections/HasValidatorContract.sol\";\nimport \"../../interfaces/staking/IBaseStaking.sol\";\nimport \"../../libraries/Math.sol\";\nimport \"./RewardCalculation.sol\";\n\nabstract contract BaseStaking is\n RONTransferHelper,\n ReentrancyGuard,\n RewardCalculation,\n HasValidatorContract,\n IBaseStaking\n{\n /// @dev Mapping from pool address => staking pool detail\n mapping(address => PoolDetail) internal _stakingPool;\n\n /// @dev The cooldown time in seconds to undelegate from the last timestamp (s)he delegated.\n uint256 internal _cooldownSecsToUndelegate;\n /// @dev The number of seconds that a candidate must wait to be revoked and take the self-staking amount back.\n uint256 internal _waitingSecsToRevoke;\n\n /// @dev Mapping from active pool admin address => consensus address.\n mapping(address => address) internal _activePoolAdminMapping;\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[49] private ______gap;\n\n modifier noEmptyValue() {\n require(msg.value > 0, \"BaseStaking: query with empty value\");\n _;\n }\n\n modifier notPoolAdmin(PoolDetail storage _pool, address _delegator) {\n require(_pool.admin != _delegator, \"BaseStaking: delegator must not be the pool admin\");\n _;\n }\n\n modifier onlyPoolAdmin(PoolDetail storage _pool, address _requester) {\n require(_pool.admin == _requester, \"BaseStaking: requester must be the pool admin\");\n _;\n }\n\n modifier poolExists(address _poolAddr) {\n require(_validatorContract.isValidatorCandidate(_poolAddr), \"BaseStaking: query for non-existent pool\");\n _;\n }\n\n /**\n * @inheritdoc IBaseStaking\n */\n function isActivePoolAdmin(address _poolAdminAddr) public view override returns (bool) {\n return _activePoolAdminMapping[_poolAdminAddr] != address(0);\n }\n\n /**\n * @inheritdoc IBaseStaking\n */\n function getPoolAddressOf(address _poolAdminAddr) external view override returns (address) {\n return _activePoolAdminMapping[_poolAdminAddr];\n }\n\n /**\n * @inheritdoc IRewardPool\n */\n function getStakingTotal(address _poolAddr) public view override returns (uint256) {\n return _stakingPool[_poolAddr].stakingTotal;\n }\n\n /**\n * @inheritdoc IRewardPool\n */\n function getManyStakingTotals(address[] calldata _poolList)\n public\n view\n override\n returns (uint256[] memory _stakingAmounts)\n {\n _stakingAmounts = new uint256[](_poolList.length);\n for (uint _i = 0; _i < _poolList.length; _i++) {\n _stakingAmounts[_i] = getStakingTotal(_poolList[_i]);\n }\n }\n\n /**\n * @inheritdoc IRewardPool\n */\n function getStakingAmount(address _poolAddr, address _user) public view override returns (uint256) {\n return _stakingPool[_poolAddr].delegatingAmount[_user];\n }\n\n /**\n * @inheritdoc IRewardPool\n */\n function getManyStakingAmounts(address[] calldata _poolAddrs, address[] calldata _userList)\n external\n view\n override\n returns (uint256[] memory _stakingAmounts)\n {\n require(_poolAddrs.length == _userList.length, \"BaseStaking: invalid input array\");\n _stakingAmounts = new uint256[](_poolAddrs.length);\n for (uint _i = 0; _i < _stakingAmounts.length; _i++) {\n _stakingAmounts[_i] = _stakingPool[_poolAddrs[_i]].delegatingAmount[_userList[_i]];\n }\n }\n\n /**\n * @inheritdoc IBaseStaking\n */\n function cooldownSecsToUndelegate() external view returns (uint256) {\n return _cooldownSecsToUndelegate;\n }\n\n /**\n * @inheritdoc IBaseStaking\n */\n function waitingSecsToRevoke() external view returns (uint256) {\n return _waitingSecsToRevoke;\n }\n\n /**\n * @inheritdoc IBaseStaking\n */\n function setCooldownSecsToUndelegate(uint256 _cooldownSecs) external override onlyAdmin {\n _setCooldownSecsToUndelegate(_cooldownSecs);\n }\n\n /**\n * @inheritdoc IBaseStaking\n */\n function setWaitingSecsToRevoke(uint256 _secs) external override onlyAdmin {\n _setWaitingSecsToRevoke(_secs);\n }\n\n /**\n * @dev Sets the minium number of seconds to undelegate.\n *\n * Emits the event `CooldownSecsToUndelegateUpdated`.\n *\n */\n function _setCooldownSecsToUndelegate(uint256 _cooldownSecs) internal {\n _cooldownSecsToUndelegate = _cooldownSecs;\n emit CooldownSecsToUndelegateUpdated(_cooldownSecs);\n }\n\n /**\n * @dev Sets the number of seconds that a candidate must wait to be revoked.\n *\n * Emits the event `WaitingSecsToRevokeUpdated`.\n *\n */\n function _setWaitingSecsToRevoke(uint256 _secs) internal {\n _waitingSecsToRevoke = _secs;\n emit WaitingSecsToRevokeUpdated(_secs);\n }\n\n /**\n * @dev Changes the delegate amount.\n */\n function _changeDelegatingAmount(\n PoolDetail storage _pool,\n address _delegator,\n uint256 _newDelegatingAmount,\n uint256 _newStakingTotal\n ) internal {\n _syncUserReward(_pool.addr, _delegator, _newDelegatingAmount);\n _pool.stakingTotal = _newStakingTotal;\n _pool.delegatingAmount[_delegator] = _newDelegatingAmount;\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "contracts/ronin/staking/RewardCalculation.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../interfaces/staking/IRewardPool.sol\";\nimport \"../../libraries/Math.sol\";\n\n/**\n * @title RewardCalculation contract\n * @dev This contract mainly contains the methods to calculate reward for staking contract.\n */\nabstract contract RewardCalculation is IRewardPool {\n /// @dev Mapping from pool address => period number => accumulated rewards per share (one unit staking)\n mapping(address => mapping(uint256 => PeriodWrapper)) private _accumulatedRps;\n /// @dev Mapping from the pool address => user address => the reward info of the user\n mapping(address => mapping(address => UserRewardFields)) private _userReward;\n /// @dev Mapping from the pool address => reward pool fields\n mapping(address => PoolFields) private _stakingPool;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n /**\n * @inheritdoc IRewardPool\n */\n function getReward(address _poolAddr, address _user) external view returns (uint256) {\n return _getReward(_poolAddr, _user, _currentPeriod(), getStakingAmount(_poolAddr, _user));\n }\n\n /**\n * @inheritdoc IRewardPool\n */\n function getStakingAmount(address _poolAddr, address _user) public view virtual returns (uint256);\n\n /**\n * @inheritdoc IRewardPool\n */\n function getStakingTotal(address _poolAddr) public view virtual returns (uint256);\n\n /**\n * @dev Returns the reward amount that user claimable.\n */\n function _getReward(\n address _poolAddr,\n address _user,\n uint256 _latestPeriod,\n uint256 _latestStakingAmount\n ) internal view returns (uint256) {\n UserRewardFields storage _reward = _userReward[_poolAddr][_user];\n\n if (_reward.lastPeriod == _latestPeriod) {\n return _reward.debited;\n }\n\n uint256 _aRps;\n uint256 _lastPeriodReward;\n PoolFields storage _pool = _stakingPool[_poolAddr];\n PeriodWrapper storage _wrappedArps = _accumulatedRps[_poolAddr][_reward.lastPeriod];\n\n if (_wrappedArps.lastPeriod > 0) {\n // Calculates the last period reward if the aRps at the period is set\n _aRps = _accumulatedRps[_poolAddr][_reward.lastPeriod].inner;\n _lastPeriodReward = _reward.minAmount * (_aRps - _reward.aRps);\n } else {\n // Fallbacks to the previous aRps in case the aRps is not set\n _aRps = _reward.aRps;\n }\n\n uint256 _newPeriodsReward = _latestStakingAmount * (_pool.aRps - _aRps);\n return _reward.debited + (_lastPeriodReward + _newPeriodsReward) / 1e18;\n }\n\n /**\n * @dev Syncs the user reward.\n *\n * Emits the event `UserRewardUpdated` once the debit amount is updated.\n * Emits the event `PoolSharesUpdated` once the pool share is updated.\n *\n * Note: The method should be called whenever the user's staking amount changes.\n *\n */\n function _syncUserReward(\n address _poolAddr,\n address _user,\n uint256 _newStakingAmount\n ) internal {\n uint256 _period = _currentPeriod();\n PoolFields storage _pool = _stakingPool[_poolAddr];\n uint256 _lastShares = _pool.shares.inner;\n\n // Updates the pool shares if it is outdated\n if (_pool.shares.lastPeriod < _period) {\n _pool.shares = PeriodWrapper(getStakingTotal(_poolAddr), _period);\n }\n\n UserRewardFields storage _reward = _userReward[_poolAddr][_user];\n uint256 _currentStakingAmount = getStakingAmount(_poolAddr, _user);\n uint256 _debited = _getReward(_poolAddr, _user, _period, _currentStakingAmount);\n\n if (_reward.debited != _debited) {\n _reward.debited = _debited;\n emit UserRewardUpdated(_poolAddr, _user, _debited);\n }\n\n _syncMinStakingAmount(_pool, _reward, _period, _newStakingAmount, _currentStakingAmount);\n _reward.aRps = _pool.aRps;\n _reward.lastPeriod = _period;\n\n if (_pool.shares.inner != _lastShares) {\n emit PoolSharesUpdated(_period, _poolAddr, _pool.shares.inner);\n }\n }\n\n /**\n * @dev Syncs the minimum staking amount of an user in the current period.\n */\n function _syncMinStakingAmount(\n PoolFields storage _pool,\n UserRewardFields storage _reward,\n uint256 _latestPeriod,\n uint256 _newStakingAmount,\n uint256 _currentStakingAmount\n ) internal {\n if (_reward.lastPeriod < _latestPeriod) {\n _reward.minAmount = _currentStakingAmount;\n }\n\n uint256 _minAmount = Math.min(_reward.minAmount, _newStakingAmount);\n uint256 _diffAmount = _reward.minAmount - _minAmount;\n if (_diffAmount > 0) {\n _reward.minAmount = _minAmount;\n require(_pool.shares.inner >= _diffAmount, \"RewardCalculation: invalid pool shares\");\n _pool.shares.inner -= _diffAmount;\n }\n }\n\n /**\n * @dev Claims the settled reward for a specific user.\n *\n * Emits the `PendingRewardUpdated` event and the `SettledRewardUpdated` event.\n *\n * Note: This method should be called before transferring rewards for the user.\n *\n */\n function _claimReward(address _poolAddr, address _user) internal returns (uint256 _amount) {\n uint256 _latestPeriod = _currentPeriod();\n _amount = _getReward(_poolAddr, _user, _latestPeriod, getStakingAmount(_poolAddr, _user));\n emit RewardClaimed(_poolAddr, _user, _amount);\n\n UserRewardFields storage _reward = _userReward[_poolAddr][_user];\n _reward.debited = 0;\n _reward.lastPeriod = _latestPeriod;\n _reward.aRps = _stakingPool[_poolAddr].aRps;\n emit UserRewardUpdated(_poolAddr, _user, 0);\n }\n\n /**\n * @dev Records the amount of rewards `_rewards` for the pools `_poolAddrs`.\n *\n * Emits the event `PoolsUpdated` once the contract recorded the rewards successfully.\n * Emits the event `PoolsUpdateFailed` once the input array lengths are not equal.\n * Emits the event `PoolUpdateConflicted` when the pool is already updated in the period.\n *\n * Note: This method should be called once at the period ending.\n *\n */\n function _recordRewards(\n address[] memory _poolAddrs,\n uint256[] calldata _rewards,\n uint256 _period\n ) internal {\n if (_poolAddrs.length != _rewards.length) {\n emit PoolsUpdateFailed(_period, _poolAddrs, _rewards);\n return;\n }\n\n uint256 _rps;\n uint256 _count;\n address _poolAddr;\n uint256 _stakingTotal;\n uint256[] memory _aRps = new uint256[](_poolAddrs.length);\n uint256[] memory _shares = new uint256[](_poolAddrs.length);\n address[] memory _conflicted = new address[](_poolAddrs.length);\n\n for (uint _i = 0; _i < _poolAddrs.length; _i++) {\n _poolAddr = _poolAddrs[_i];\n PoolFields storage _pool = _stakingPool[_poolAddr];\n _stakingTotal = getStakingTotal(_poolAddr);\n\n if (_accumulatedRps[_poolAddr][_period].lastPeriod == _period) {\n _conflicted[_count++] = _poolAddr;\n continue;\n }\n\n // Updates the pool shares if it is outdated\n if (_pool.shares.lastPeriod < _period) {\n _pool.shares = PeriodWrapper(_stakingTotal, _period);\n }\n\n // The rps is 0 if no one stakes for the pool\n _rps = _pool.shares.inner == 0 ? 0 : (_rewards[_i] * 1e18) / _pool.shares.inner;\n _aRps[_i - _count] = _pool.aRps += _rps;\n _accumulatedRps[_poolAddr][_period] = PeriodWrapper(_pool.aRps, _period);\n if (_pool.shares.inner != _stakingTotal) {\n _pool.shares.inner = _stakingTotal;\n }\n _shares[_i - _count] = _pool.shares.inner;\n _poolAddrs[_i - _count] = _poolAddr;\n }\n\n if (_count > 0) {\n assembly {\n mstore(_conflicted, _count)\n mstore(_poolAddrs, sub(mload(_poolAddrs), _count))\n }\n emit PoolsUpdateConflicted(_period, _conflicted);\n }\n\n if (_poolAddrs.length > 0) {\n emit PoolsUpdated(_period, _poolAddrs, _aRps, _shares);\n }\n }\n\n /**\n * @dev Returns the current period.\n */\n function _currentPeriod() internal view virtual returns (uint256);\n}\n" + }, + "contracts/ronin/Maintenance.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IMaintenance.sol\";\nimport \"../interfaces/validator/IRoninValidatorSet.sol\";\nimport \"../extensions/collections/HasValidatorContract.sol\";\nimport \"../libraries/Math.sol\";\n\ncontract Maintenance is IMaintenance, HasValidatorContract, Initializable {\n using Math for uint256;\n\n /// @dev Mapping from consensus address => maintenance schedule.\n mapping(address => Schedule) internal _schedule;\n\n /// @dev The min duration to maintenance in blocks.\n uint256 public minMaintenanceDurationInBlock;\n /// @dev The max duration to maintenance in blocks.\n uint256 public maxMaintenanceDurationInBlock;\n /// @dev The offset to the min block number that the schedule can start.\n uint256 public minOffsetToStartSchedule;\n /// @dev The offset to the max block number that the schedule can start.\n uint256 public maxOffsetToStartSchedule;\n /// @dev The max number of scheduled maintenances.\n uint256 public maxSchedules;\n\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @dev Initializes the contract storage.\n */\n function initialize(\n address __validatorContract,\n uint256 _minMaintenanceDurationInBlock,\n uint256 _maxMaintenanceDurationInBlock,\n uint256 _minOffsetToStartSchedule,\n uint256 _maxOffsetToStartSchedule,\n uint256 _maxSchedules\n ) external initializer {\n _setValidatorContract(__validatorContract);\n _setMaintenanceConfig(\n _minMaintenanceDurationInBlock,\n _maxMaintenanceDurationInBlock,\n _minOffsetToStartSchedule,\n _maxOffsetToStartSchedule,\n _maxSchedules\n );\n }\n\n /**\n * @inheritdoc IMaintenance\n */\n function setMaintenanceConfig(\n uint256 _minMaintenanceDurationInBlock,\n uint256 _maxMaintenanceDurationInBlock,\n uint256 _minOffsetToStartSchedule,\n uint256 _maxOffsetToStartSchedule,\n uint256 _maxSchedules\n ) external onlyAdmin {\n _setMaintenanceConfig(\n _minMaintenanceDurationInBlock,\n _maxMaintenanceDurationInBlock,\n _minOffsetToStartSchedule,\n _maxOffsetToStartSchedule,\n _maxSchedules\n );\n }\n\n /**\n * @inheritdoc IMaintenance\n */\n function schedule(\n address _consensusAddr,\n uint256 _startedAtBlock,\n uint256 _endedAtBlock\n ) external override {\n IRoninValidatorSet _validator = _validatorContract;\n\n require(_validator.isBlockProducer(_consensusAddr), \"Maintenance: consensus address must be a block producer\");\n require(\n _validator.isCandidateAdmin(_consensusAddr, msg.sender),\n \"Maintenance: method caller must be a candidate admin\"\n );\n require(!checkScheduled(_consensusAddr), \"Maintenance: already scheduled\");\n require(totalSchedules() < maxSchedules, \"Maintenance: exceeds total of schedules\");\n require(\n _startedAtBlock.inRange(block.number + minOffsetToStartSchedule, block.number + maxOffsetToStartSchedule),\n \"Maintenance: start block is out of offset\"\n );\n require(_startedAtBlock < _endedAtBlock, \"Maintenance: start block must be less than end block\");\n uint256 _blockPeriod = _endedAtBlock - _startedAtBlock;\n require(\n _blockPeriod.inRange(minMaintenanceDurationInBlock, maxMaintenanceDurationInBlock),\n \"Maintenance: invalid maintenance duration\"\n );\n require(_validator.epochEndingAt(_startedAtBlock - 1), \"Maintenance: start block is not at the start of an epoch\");\n require(_validator.epochEndingAt(_endedAtBlock), \"Maintenance: end block is not at the end of an epoch\");\n\n Schedule storage _sSchedule = _schedule[_consensusAddr];\n _sSchedule.from = _startedAtBlock;\n _sSchedule.to = _endedAtBlock;\n _sSchedule.lastUpdatedBlock = block.number;\n emit MaintenanceScheduled(_consensusAddr, _sSchedule);\n }\n\n /**\n * @inheritdoc IMaintenance\n */\n function getSchedule(address _consensusAddr) external view returns (Schedule memory) {\n return _schedule[_consensusAddr];\n }\n\n /**\n * @inheritdoc IMaintenance\n */\n function checkManyMaintained(address[] calldata _addrList, uint256 _block)\n external\n view\n override\n returns (bool[] memory _resList)\n {\n _resList = new bool[](_addrList.length);\n for (uint _i = 0; _i < _addrList.length; _i++) {\n _resList[_i] = checkMaintained(_addrList[_i], _block);\n }\n }\n\n /**\n * @inheritdoc IMaintenance\n */\n function checkManyMaintainedInBlockRange(\n address[] calldata _addrList,\n uint256 _fromBlock,\n uint256 _toBlock\n ) external view override returns (bool[] memory _resList) {\n _resList = new bool[](_addrList.length);\n for (uint _i = 0; _i < _addrList.length; _i++) {\n _resList[_i] = _maintainingInBlockRange(_addrList[_i], _fromBlock, _toBlock);\n }\n }\n\n /**\n * @inheritdoc IMaintenance\n */\n function totalSchedules() public view override returns (uint256 _count) {\n address[] memory _validators = _validatorContract.getValidators();\n for (uint _i = 0; _i < _validators.length; _i++) {\n if (checkScheduled(_validators[_i])) {\n _count++;\n }\n }\n }\n\n /**\n * @inheritdoc IMaintenance\n */\n function checkMaintained(address _consensusAddr, uint256 _block) public view returns (bool) {\n Schedule storage _s = _schedule[_consensusAddr];\n return _s.from <= _block && _block <= _s.to;\n }\n\n /**\n * @inheritdoc IMaintenance\n */\n function checkMaintainedInBlockRange(\n address _consensusAddr,\n uint256 _fromBlock,\n uint256 _toBlock\n ) public view override returns (bool) {\n return _maintainingInBlockRange(_consensusAddr, _fromBlock, _toBlock);\n }\n\n /**\n * @inheritdoc IMaintenance\n */\n function checkScheduled(address _consensusAddr) public view override returns (bool) {\n return block.number <= _schedule[_consensusAddr].to;\n }\n\n /**\n * @dev Sets the min block period and max block period to maintenance.\n *\n * Requirements:\n * - The max period is larger than the min period.\n *\n * Emits the event `MaintenanceConfigUpdated`.\n *\n */\n function _setMaintenanceConfig(\n uint256 _minMaintenanceDurationInBlock,\n uint256 _maxMaintenanceDurationInBlock,\n uint256 _minOffsetToStartSchedule,\n uint256 _maxOffsetToStartSchedule,\n uint256 _maxSchedules\n ) internal {\n require(\n _minMaintenanceDurationInBlock < _maxMaintenanceDurationInBlock,\n \"Maintenance: invalid maintenance duration configs\"\n );\n require(\n _minOffsetToStartSchedule < _maxOffsetToStartSchedule,\n \"Maintenance: invalid offset to start schedule configs\"\n );\n minMaintenanceDurationInBlock = _minMaintenanceDurationInBlock;\n maxMaintenanceDurationInBlock = _maxMaintenanceDurationInBlock;\n minOffsetToStartSchedule = _minOffsetToStartSchedule;\n maxOffsetToStartSchedule = _maxOffsetToStartSchedule;\n maxSchedules = _maxSchedules;\n emit MaintenanceConfigUpdated(\n _minMaintenanceDurationInBlock,\n _maxMaintenanceDurationInBlock,\n _minOffsetToStartSchedule,\n _maxOffsetToStartSchedule,\n _maxSchedules\n );\n }\n\n /**\n * @dev Check if the validator was maintaining in the current period.\n *\n * Note: This method should be called at the end of the period.\n */\n function _maintainingInBlockRange(\n address _consensusAddr,\n uint256 _fromBlock,\n uint256 _toBlock\n ) private view returns (bool) {\n Schedule storage _s = _schedule[_consensusAddr];\n return Math.twoRangeOverlap(_fromBlock, _toBlock, _s.from, _s.to);\n }\n}\n" + }, + "contracts/ronin/StakingVesting.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IStakingVesting.sol\";\nimport \"../extensions/collections/HasValidatorContract.sol\";\nimport \"../extensions/RONTransferHelper.sol\";\n\ncontract StakingVesting is IStakingVesting, HasValidatorContract, RONTransferHelper, Initializable {\n /// @dev The block bonus for the block producer whenever a new block is mined.\n uint256 internal _blockProducerBonusPerBlock;\n /// @dev The block bonus for the bridge operator whenever a new block is mined.\n uint256 internal _bridgeOperatorBonusPerBlock;\n /// @dev The last block number that the staking vesting sent.\n uint256 public lastBlockSendingBonus;\n\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @dev Initializes the contract storage.\n */\n function initialize(\n address __validatorContract,\n uint256 __blockProducerBonusPerBlock,\n uint256 __bridgeOperatorBonusPerBlock\n ) external payable initializer {\n _setValidatorContract(__validatorContract);\n _setBlockProducerBonusPerBlock(__blockProducerBonusPerBlock);\n _setBridgeOperatorBonusPerBlock(__bridgeOperatorBonusPerBlock);\n }\n\n /**\n * @inheritdoc IStakingVesting\n */\n function receiveRON() external payable {}\n\n /**\n * @inheritdoc IStakingVesting\n */\n function blockProducerBlockBonus(\n uint256 /* _block */\n ) public view override returns (uint256) {\n return _blockProducerBonusPerBlock;\n }\n\n /**\n * @inheritdoc IStakingVesting\n */\n function bridgeOperatorBlockBonus(\n uint256 /* _block */\n ) public view override returns (uint256) {\n return _bridgeOperatorBonusPerBlock;\n }\n\n /**\n * @inheritdoc IStakingVesting\n */\n function requestBonus(bool _forBlockProducer, bool _forBridgeOperator)\n external\n override\n onlyValidatorContract\n returns (\n bool _success,\n uint256 _blockProducerBonus,\n uint256 _bridgeOperatorBonus\n )\n {\n require(block.number > lastBlockSendingBonus, \"StakingVesting: bonus for already sent\");\n lastBlockSendingBonus = block.number;\n\n _blockProducerBonus = _forBlockProducer ? blockProducerBlockBonus(block.number) : 0;\n _bridgeOperatorBonus = _forBridgeOperator ? bridgeOperatorBlockBonus(block.number) : 0;\n\n uint256 _totalAmount = _blockProducerBonus + _bridgeOperatorBonus;\n\n if (_totalAmount > 0) {\n address payable _validatorContractAddr = payable(validatorContract());\n\n _success = _unsafeSendRON(_validatorContractAddr, _totalAmount);\n\n if (!_success) {\n emit BonusTransferFailed(\n block.number,\n _validatorContractAddr,\n _blockProducerBonus,\n _bridgeOperatorBonus,\n address(this).balance\n );\n return (_success, 0, 0);\n }\n\n emit BonusTransferred(block.number, _validatorContractAddr, _blockProducerBonus, _bridgeOperatorBonus);\n }\n }\n\n /**\n * @inheritdoc IStakingVesting\n */\n function setBlockProducerBonusPerBlock(uint256 _amount) external override onlyAdmin {\n _setBlockProducerBonusPerBlock(_amount);\n }\n\n /**\n * @inheritdoc IStakingVesting\n */\n function setBridgeOperatorBonusPerBlock(uint256 _amount) external override onlyAdmin {\n _setBridgeOperatorBonusPerBlock(_amount);\n }\n\n /**\n * @dev Sets the bonus amount per block for block producer.\n *\n * Emits the event `BlockProducerBonusPerBlockUpdated`.\n *\n */\n function _setBlockProducerBonusPerBlock(uint256 _amount) internal {\n _blockProducerBonusPerBlock = _amount;\n emit BlockProducerBonusPerBlockUpdated(_amount);\n }\n\n /**\n * @dev Sets the bonus amount per block for bridge operator.\n *\n * Emits the event `BridgeOperatorBonusPerBlockUpdated`.\n *\n */\n function _setBridgeOperatorBonusPerBlock(uint256 _amount) internal {\n _bridgeOperatorBonusPerBlock = _amount;\n emit BridgeOperatorBonusPerBlockUpdated(_amount);\n }\n}\n" + }, + "contracts/multi-chains/RoninTrustedOrganization.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport \"../libraries/AddressArrayUtils.sol\";\nimport \"../interfaces/IRoninTrustedOrganization.sol\";\nimport \"../extensions/collections/HasProxyAdmin.sol\";\n\ncontract RoninTrustedOrganization is IRoninTrustedOrganization, HasProxyAdmin, Initializable {\n uint256 internal _num;\n uint256 internal _denom;\n uint256 internal _totalWeight;\n uint256 internal _nonce;\n\n /// @dev Mapping from consensus address => weight\n mapping(address => uint256) internal _consensusWeight;\n /// @dev Mapping from governor address => weight\n mapping(address => uint256) internal _governorWeight;\n /// @dev Mapping from bridge voter address => weight\n mapping(address => uint256) internal _bridgeVoterWeight;\n\n /// @dev Mapping from consensus address => added block\n mapping(address => uint256) internal _addedBlock;\n\n /// @dev Consensus array\n address[] internal _consensusList;\n /// @dev Governors array\n address[] internal _governorList;\n /// @dev Bridge voters array\n address[] internal _bridgeVoterList;\n\n /**\n * @dev Initializes the contract storage.\n */\n function initialize(\n TrustedOrganization[] calldata _trustedOrgs,\n uint256 __num,\n uint256 __denom\n ) external initializer {\n if (_trustedOrgs.length > 0) {\n _addTrustedOrganizations(_trustedOrgs);\n }\n _setThreshold(__num, __denom);\n }\n\n /**\n * @inheritdoc IQuorum\n */\n function getThreshold() external view virtual returns (uint256, uint256) {\n return (_num, _denom);\n }\n\n /**\n * @inheritdoc IQuorum\n */\n function checkThreshold(uint256 _voteWeight) external view virtual returns (bool) {\n return _voteWeight * _denom >= _num * _totalWeight;\n }\n\n /**\n * @inheritdoc IQuorum\n */\n function minimumVoteWeight() external view virtual returns (uint256) {\n return (_num * _totalWeight + _denom - 1) / _denom;\n }\n\n /**\n * @inheritdoc IQuorum\n */\n function setThreshold(uint256 _numerator, uint256 _denominator)\n external\n override\n onlyAdmin\n returns (uint256, uint256)\n {\n return _setThreshold(_numerator, _denominator);\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function addTrustedOrganizations(TrustedOrganization[] calldata _list) external override onlyAdmin {\n _addTrustedOrganizations(_list);\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function updateTrustedOrganizations(TrustedOrganization[] calldata _list) external override onlyAdmin {\n require(_list.length > 0, \"RoninTrustedOrganization: invalid array length\");\n for (uint256 _i; _i < _list.length; _i++) {\n _updateTrustedOrganization(_list[_i]);\n }\n emit TrustedOrganizationsUpdated(_list);\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function removeTrustedOrganizations(address[] calldata _list) external override onlyAdmin {\n require(_list.length > 0, \"RoninTrustedOrganization: invalid array length\");\n for (uint _i = 0; _i < _list.length; _i++) {\n _removeTrustedOrganization(_list[_i]);\n }\n emit TrustedOrganizationsRemoved(_list);\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function totalWeights() external view virtual returns (uint256) {\n return _totalWeight;\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function getConsensusWeight(address _consensusAddr) external view returns (uint256) {\n return _consensusWeight[_consensusAddr];\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function getGovernorWeight(address _governor) external view returns (uint256) {\n return _governorWeight[_governor];\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function getBridgeVoterWeight(address _addr) external view returns (uint256) {\n return _bridgeVoterWeight[_addr];\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function getConsensusWeights(address[] calldata _list) external view returns (uint256[] memory _res) {\n _res = new uint256[](_list.length);\n for (uint _i = 0; _i < _res.length; _i++) {\n _res[_i] = _consensusWeight[_list[_i]];\n }\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function getGovernorWeights(address[] calldata _list) external view returns (uint256[] memory _res) {\n _res = new uint256[](_list.length);\n for (uint _i = 0; _i < _res.length; _i++) {\n _res[_i] = _governorWeight[_list[_i]];\n }\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function getBridgeVoterWeights(address[] calldata _list) external view returns (uint256[] memory _res) {\n _res = new uint256[](_list.length);\n for (uint _i = 0; _i < _res.length; _i++) {\n _res[_i] = _bridgeVoterWeight[_list[_i]];\n }\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function sumConsensusWeights(address[] calldata _list) external view returns (uint256 _res) {\n for (uint _i = 0; _i < _list.length; _i++) {\n _res += _consensusWeight[_list[_i]];\n }\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function sumGovernorWeights(address[] calldata _list) external view returns (uint256 _res) {\n for (uint _i = 0; _i < _list.length; _i++) {\n _res += _governorWeight[_list[_i]];\n }\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function sumBridgeVoterWeights(address[] calldata _list) external view returns (uint256 _res) {\n for (uint _i = 0; _i < _list.length; _i++) {\n _res += _bridgeVoterWeight[_list[_i]];\n }\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function countTrustedOrganizations() external view override returns (uint256) {\n return _consensusList.length;\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function getAllTrustedOrganizations() external view override returns (TrustedOrganization[] memory _list) {\n _list = new TrustedOrganization[](_consensusList.length);\n address _addr;\n for (uint256 _i; _i < _list.length; _i++) {\n _addr = _consensusList[_i];\n _list[_i].consensusAddr = _addr;\n _list[_i].governor = _governorList[_i];\n _list[_i].bridgeVoter = _bridgeVoterList[_i];\n _list[_i].weight = _consensusWeight[_addr];\n }\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function getTrustedOrganization(address _consensusAddr) external view returns (TrustedOrganization memory) {\n for (uint _i = 0; _i < _consensusList.length; _i++) {\n if (_consensusList[_i] == _consensusAddr) {\n return getTrustedOrganizationAt(_i);\n }\n }\n revert(\"RoninTrustedOrganization: query for non-existent consensus address\");\n }\n\n /**\n * @inheritdoc IRoninTrustedOrganization\n */\n function getTrustedOrganizationAt(uint256 _idx) public view override returns (TrustedOrganization memory) {\n address _addr = _consensusList[_idx];\n return\n TrustedOrganization(\n _addr,\n _governorList[_idx],\n _bridgeVoterList[_idx],\n _consensusWeight[_addr],\n _addedBlock[_addr]\n );\n }\n\n /**\n * @dev Adds a list of trusted organizations.\n */\n function _addTrustedOrganizations(TrustedOrganization[] calldata _list) internal virtual {\n for (uint256 _i; _i < _list.length; _i++) {\n _addTrustedOrganization(_list[_i]);\n }\n emit TrustedOrganizationsAdded(_list);\n }\n\n /**\n * @dev Adds a trusted organization.\n *\n * Requirements:\n * - The weight is larger than 0.\n * - The consensus address is not added.\n * - The govenor address is not added.\n * - The bridge voter address is not added.\n *\n */\n function _addTrustedOrganization(TrustedOrganization memory _v) internal virtual {\n require(_v.addedBlock == 0, \"RoninTrustedOrganization: invalid request\");\n require(_v.weight > 0, \"RoninTrustedOrganization: invalid weight\");\n\n address[] memory _addresses = new address[](3);\n _addresses[0] = _v.consensusAddr;\n _addresses[1] = _v.governor;\n _addresses[2] = _v.bridgeVoter;\n require(!AddressArrayUtils.hasDuplicate(_addresses), \"RoninTrustedOrganization: three addresses must be distinct\");\n\n if (_consensusWeight[_v.consensusAddr] > 0) {\n revert(\n string(\n abi.encodePacked(\n \"RoninTrustedOrganization: consensus address \",\n Strings.toHexString(uint160(_v.consensusAddr), 20),\n \" is added already\"\n )\n )\n );\n }\n\n if (_governorWeight[_v.governor] > 0) {\n revert(\n string(\n abi.encodePacked(\n \"RoninTrustedOrganization: govenor address \",\n Strings.toHexString(uint160(_v.governor), 20),\n \" is added already\"\n )\n )\n );\n }\n\n if (_bridgeVoterWeight[_v.bridgeVoter] > 0) {\n revert(\n string(\n abi.encodePacked(\n \"RoninTrustedOrganization: bridge voter address \",\n Strings.toHexString(uint160(_v.bridgeVoter), 20),\n \" is added already\"\n )\n )\n );\n }\n\n _consensusList.push(_v.consensusAddr);\n _consensusWeight[_v.consensusAddr] = _v.weight;\n\n _governorList.push(_v.governor);\n _governorWeight[_v.governor] = _v.weight;\n\n _bridgeVoterList.push(_v.bridgeVoter);\n _bridgeVoterWeight[_v.bridgeVoter] = _v.weight;\n\n _addedBlock[_v.consensusAddr] = block.number;\n\n _totalWeight += _v.weight;\n }\n\n /**\n * @dev Updates a trusted organization.\n *\n * Requirements:\n * - The weight is larger than 0.\n * - The consensus address is already added.\n *\n */\n function _updateTrustedOrganization(TrustedOrganization memory _v) internal virtual {\n require(_v.weight > 0, \"RoninTrustedOrganization: invalid weight\");\n\n uint256 _weight = _consensusWeight[_v.consensusAddr];\n if (_weight == 0) {\n revert(\n string(\n abi.encodePacked(\n \"RoninTrustedOrganization: consensus address \",\n Strings.toHexString(uint160(_v.consensusAddr), 20),\n \" is not added\"\n )\n )\n );\n }\n\n uint256 _count = _consensusList.length;\n for (uint256 _i = 0; _i < _count; _i++) {\n if (_consensusList[_i] == _v.consensusAddr) {\n _totalWeight -= _weight;\n _totalWeight += _v.weight;\n\n if (_governorList[_i] != _v.governor) {\n require(_governorWeight[_v.governor] == 0, \"RoninTrustedOrganization: query for duplicated governor\");\n delete _governorWeight[_governorList[_i]];\n _governorList[_i] = _v.governor;\n }\n\n if (_bridgeVoterList[_i] != _v.bridgeVoter) {\n require(\n _bridgeVoterWeight[_v.bridgeVoter] == 0,\n \"RoninTrustedOrganization: query for duplicated bridge voter\"\n );\n delete _bridgeVoterWeight[_bridgeVoterList[_i]];\n _bridgeVoterList[_i] = _v.governor;\n }\n\n _consensusWeight[_v.consensusAddr] = _v.weight;\n _governorWeight[_v.governor] = _v.weight;\n _bridgeVoterWeight[_v.bridgeVoter] = _v.weight;\n return;\n }\n }\n }\n\n /**\n * @dev Removes a trusted organization.\n *\n * Requirements:\n * - The consensus address is added.\n *\n */\n function _removeTrustedOrganization(address _addr) internal virtual {\n uint256 _weight = _consensusWeight[_addr];\n if (_weight == 0) {\n revert(\n string(\n abi.encodePacked(\n \"RoninTrustedOrganization: consensus address \",\n Strings.toHexString(uint160(_addr), 20),\n \" is not added\"\n )\n )\n );\n }\n\n uint256 _index;\n uint256 _count = _consensusList.length;\n for (uint256 _i = 0; _i < _count; _i++) {\n if (_consensusList[_i] == _addr) {\n _index = _i;\n break;\n }\n }\n\n _totalWeight -= _weight;\n\n delete _addedBlock[_addr];\n delete _consensusWeight[_addr];\n _consensusList[_index] = _consensusList[_count - 1];\n _consensusList.pop();\n\n delete _governorWeight[_governorList[_index]];\n _governorList[_index] = _governorList[_count - 1];\n _governorList.pop();\n\n delete _bridgeVoterWeight[_bridgeVoterList[_index]];\n _bridgeVoterList[_index] = _bridgeVoterList[_count - 1];\n _bridgeVoterList.pop();\n }\n\n /**\n * @dev Sets threshold and returns the old one.\n *\n * Emits the `ThresholdUpdated` event.\n *\n */\n function _setThreshold(uint256 _numerator, uint256 _denominator)\n internal\n virtual\n returns (uint256 _previousNum, uint256 _previousDenom)\n {\n require(_numerator <= _denominator, \"RoninTrustedOrganization: invalid threshold\");\n _previousNum = _num;\n _previousDenom = _denom;\n _num = _numerator;\n _denom = _denominator;\n emit ThresholdUpdated(_nonce++, _numerator, _denominator, _previousNum, _previousDenom);\n }\n}\n" + }, + "contracts/extensions/GovernanceAdmin.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../extensions/sequential-governance/CoreGovernance.sol\";\nimport \"../extensions/collections/HasRoninTrustedOrganizationContract.sol\";\nimport \"../extensions/collections/HasBridgeContract.sol\";\nimport \"../interfaces/IRoninTrustedOrganization.sol\";\n\nabstract contract GovernanceAdmin is CoreGovernance, HasRoninTrustedOrganizationContract, HasBridgeContract {\n /// @dev Domain separator\n bytes32 public constant DOMAIN_SEPARATOR = 0xf8704f8860d9e985bf6c52ec4738bd10fe31487599b36c0944f746ea09dc256b;\n\n modifier onlySelfCall() {\n require(msg.sender == address(this), \"GovernanceAdmin: only allowed self-call\");\n _;\n }\n\n constructor(\n address _roninTrustedOrganizationContract,\n address _bridgeContract,\n uint256 _proposalExpiryDuration\n ) CoreGovernance(_proposalExpiryDuration) {\n require(\n keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,bytes32 salt)\"),\n keccak256(\"GovernanceAdmin\"), // name hash\n keccak256(\"1\"), // version hash\n keccak256(abi.encode(\"RONIN_GOVERNANCE_ADMIN\", 2020)) // salt\n )\n ) == DOMAIN_SEPARATOR,\n \"GovernanceAdmin: invalid domain\"\n );\n _setRoninTrustedOrganizationContract(_roninTrustedOrganizationContract);\n _setBridgeContract(_bridgeContract);\n }\n\n /**\n * @inheritdoc IHasRoninTrustedOrganizationContract\n */\n function setRoninTrustedOrganizationContract(address _addr) external override onlySelfCall {\n require(_addr.code.length > 0, \"GovernanceAdmin: set to non-contract\");\n _setRoninTrustedOrganizationContract(_addr);\n }\n\n /**\n * @inheritdoc IHasBridgeContract\n */\n function setBridgeContract(address _addr) external override onlySelfCall {\n require(_addr.code.length > 0, \"GovernanceAdmin: set to non-contract\");\n _setBridgeContract(_addr);\n }\n\n /**\n * @dev Sets the expiry duration for a new proposal.\n *\n * Requirements:\n * - Only allowing self-call to this method, since this contract does not have admin.\n *\n */\n function setProposalExpiryDuration(uint256 _expiryDuration) external onlySelfCall {\n _setProposalExpiryDuration(_expiryDuration);\n }\n\n /**\n * @dev Returns the current implementation of `_proxy`.\n *\n * Requirements:\n * - This contract must be the admin of `_proxy`.\n *\n */\n function getProxyImplementation(address _proxy) external view returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool _success, bytes memory _returndata) = _proxy.staticcall(hex\"5c60da1b\");\n require(_success, \"GovernanceAdmin: proxy call `implementation()` failed\");\n return abi.decode(_returndata, (address));\n }\n\n /**\n * @dev Returns the proposal expiry duration.\n */\n function getProposalExpiryDuration() external view returns (uint256) {\n return super._getProposalExpiryDuration();\n }\n\n /**\n * @dev Returns the current admin of `_proxy`.\n *\n * Requirements:\n * - This contract must be the admin of `_proxy`.\n *\n */\n function getProxyAdmin(address _proxy) external view returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool _success, bytes memory _returndata) = _proxy.staticcall(hex\"f851a440\");\n require(_success, \"GovernanceAdmin: proxy call `admin()` failed\");\n return abi.decode(_returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `_proxy` to `newAdmin`.\n *\n * Requirements:\n * - This contract must be the current admin of `_proxy`.\n *\n */\n function changeProxyAdmin(address _proxy, address _newAdmin) external onlySelfCall {\n // bytes4(keccak256(\"changeAdmin(address)\"))\n (bool _success, ) = _proxy.call(abi.encodeWithSelector(0x8f283970, _newAdmin));\n require(_success, \"GovernanceAdmin: proxy call `changeAdmin(address)` failed\");\n }\n\n /**\n * @dev Override `CoreGovernance-_getMinimumVoteWeight`.\n */\n function _getMinimumVoteWeight() internal view virtual override returns (uint256) {\n (bool _success, bytes memory _returndata) = roninTrustedOrganizationContract().staticcall(\n abi.encodeWithSelector(\n // TransparentUpgradeableProxyV2.functionDelegateCall.selector,\n 0x4bb5274a,\n abi.encodeWithSelector(IQuorum.minimumVoteWeight.selector)\n )\n );\n require(_success, \"GovernanceAdmin: proxy call `minimumVoteWeight()` failed\");\n return abi.decode(_returndata, (uint256));\n }\n\n /**\n * @dev Override `CoreGovernance-_getTotalWeights`.\n */\n function _getTotalWeights() internal view virtual override returns (uint256) {\n (bool _success, bytes memory _returndata) = roninTrustedOrganizationContract().staticcall(\n abi.encodeWithSelector(\n // TransparentUpgradeableProxyV2.functionDelegateCall.selector,\n 0x4bb5274a,\n abi.encodeWithSelector(IRoninTrustedOrganization.totalWeights.selector)\n )\n );\n require(_success, \"GovernanceAdmin: proxy call `totalWeights()` failed\");\n return abi.decode(_returndata, (uint256));\n }\n}\n" + }, + "contracts/extensions/sequential-governance/CoreGovernance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"../../libraries/Proposal.sol\";\nimport \"../../libraries/GlobalProposal.sol\";\nimport \"../../libraries/Ballot.sol\";\nimport \"../../interfaces/consumers/ChainTypeConsumer.sol\";\nimport \"../../interfaces/consumers/SignatureConsumer.sol\";\nimport \"../../interfaces/consumers/VoteStatusConsumer.sol\";\n\nabstract contract CoreGovernance is SignatureConsumer, VoteStatusConsumer, ChainTypeConsumer {\n using Proposal for Proposal.ProposalDetail;\n using GlobalProposal for GlobalProposal.GlobalProposalDetail;\n\n struct ProposalVote {\n VoteStatus status;\n bytes32 hash;\n uint256 againstVoteWeight; // Total weight of against votes\n uint256 forVoteWeight; // Total weight of for votes\n address[] forVoteds; // Array of addresses voting for\n address[] againstVoteds; // Array of addresses voting against\n uint256 expiryTimestamp;\n mapping(address => Signature) sig;\n }\n\n /// @dev Emitted when a proposal is created\n event ProposalCreated(\n uint256 indexed chainId,\n uint256 indexed round,\n bytes32 indexed proposalHash,\n Proposal.ProposalDetail proposal,\n address creator\n );\n /// @dev Emitted when a proposal is created\n event GlobalProposalCreated(\n uint256 indexed round,\n bytes32 indexed proposalHash,\n Proposal.ProposalDetail proposal,\n bytes32 globalProposalHash,\n GlobalProposal.GlobalProposalDetail globalProposal,\n address creator\n );\n /// @dev Emitted when the proposal is voted\n event ProposalVoted(bytes32 indexed proposalHash, address indexed voter, Ballot.VoteType support, uint256 weight);\n /// @dev Emitted when the proposal is approved\n event ProposalApproved(bytes32 indexed proposalHash);\n /// @dev Emitted when the vote is reject\n event ProposalRejected(bytes32 indexed proposalHash);\n /// @dev Emitted when the vote is expired\n event ProposalExpired(bytes32 indexed proposalHash);\n /// @dev Emitted when the proposal is executed\n event ProposalExecuted(bytes32 indexed proposalHash, bool[] successCalls, bytes[] returnDatas);\n\n /// @dev Mapping from chain id => vote round\n /// @notice chain id = 0 for global proposal\n mapping(uint256 => uint256) public round;\n /// @dev Mapping from chain id => vote round => proposal vote\n mapping(uint256 => mapping(uint256 => ProposalVote)) public vote;\n\n uint256 private _proposalExpiryDuration;\n\n constructor(uint256 _expiryDuration) {\n _setProposalExpiryDuration(_expiryDuration);\n }\n\n /**\n * @dev Creates new round voting for the proposal `_proposalHash` of chain `_chainId`.\n */\n function _createVotingRound(\n uint256 _chainId,\n bytes32 _proposalHash,\n uint256 _expiryTimestamp\n ) internal returns (uint256 _round) {\n _round = round[_chainId];\n\n // Skip checking for the first ever round\n if (_round == 0) {\n _round = round[_chainId] = 1;\n } else {\n ProposalVote storage _latestProposalVote = vote[_chainId][_round];\n bool _isExpired = _tryDeleteExpiredVotingRound(_latestProposalVote);\n // Skip increase round number if the latest round is expired, allow the vote to be overridden\n if (!_isExpired) {\n require(_latestProposalVote.status != VoteStatus.Pending, \"CoreGovernance: current proposal is not completed\");\n _round = ++round[_chainId];\n }\n }\n\n vote[_chainId][_round].hash = _proposalHash;\n vote[_chainId][_round].expiryTimestamp = _expiryTimestamp;\n }\n\n /**\n * @dev Proposes for a new proposal.\n *\n * Requirements:\n * - The chain id is not equal to 0.\n *\n * Emits the `ProposalCreated` event.\n *\n */\n function _proposeProposal(\n uint256 _chainId,\n uint256 _expiryTimestamp,\n address[] memory _targets,\n uint256[] memory _values,\n bytes[] memory _calldatas,\n uint256[] memory _gasAmounts,\n address _creator\n ) internal virtual returns (uint256 _round) {\n require(_chainId != 0, \"CoreGovernance: invalid chain id\");\n\n Proposal.ProposalDetail memory _proposal = Proposal.ProposalDetail(\n round[_chainId] + 1,\n _chainId,\n _expiryTimestamp,\n _targets,\n _values,\n _calldatas,\n _gasAmounts\n );\n _proposal.validate(_proposalExpiryDuration);\n\n bytes32 _proposalHash = _proposal.hash();\n _round = _createVotingRound(_chainId, _proposalHash, _expiryTimestamp);\n emit ProposalCreated(_chainId, _round, _proposalHash, _proposal, _creator);\n }\n\n /**\n * @dev Proposes proposal struct.\n *\n * Requirements:\n * - The chain id is not equal to 0.\n * - The proposal nonce is equal to the new round.\n *\n * Emits the `ProposalCreated` event.\n *\n */\n function _proposeProposalStruct(Proposal.ProposalDetail memory _proposal, address _creator)\n internal\n virtual\n returns (uint256 _round)\n {\n uint256 _chainId = _proposal.chainId;\n require(_chainId != 0, \"CoreGovernance: invalid chain id\");\n _proposal.validate(_proposalExpiryDuration);\n\n bytes32 _proposalHash = _proposal.hash();\n _round = _createVotingRound(_chainId, _proposalHash, _proposal.expiryTimestamp);\n require(_round == _proposal.nonce, \"CoreGovernance: invalid proposal nonce\");\n emit ProposalCreated(_chainId, _round, _proposalHash, _proposal, _creator);\n }\n\n /**\n * @dev Proposes for a global proposal.\n *\n * Emits the `GlobalProposalCreated` event.\n *\n */\n function _proposeGlobal(\n uint256 _expiryTimestamp,\n GlobalProposal.TargetOption[] calldata _targetOptions,\n uint256[] memory _values,\n bytes[] memory _calldatas,\n uint256[] memory _gasAmounts,\n address _roninTrustedOrganizationContract,\n address _gatewayContract,\n address _creator\n ) internal virtual returns (uint256 _round) {\n GlobalProposal.GlobalProposalDetail memory _globalProposal = GlobalProposal.GlobalProposalDetail(\n round[0] + 1,\n _expiryTimestamp,\n _targetOptions,\n _values,\n _calldatas,\n _gasAmounts\n );\n Proposal.ProposalDetail memory _proposal = _globalProposal.into_proposal_detail(\n _roninTrustedOrganizationContract,\n _gatewayContract\n );\n _proposal.validate(_proposalExpiryDuration);\n\n bytes32 _proposalHash = _proposal.hash();\n _round = _createVotingRound(0, _proposalHash, _expiryTimestamp);\n emit GlobalProposalCreated(_round, _proposalHash, _proposal, _globalProposal.hash(), _globalProposal, _creator);\n }\n\n /**\n * @dev Proposes global proposal struct.\n *\n * Requirements:\n * - The proposal nonce is equal to the new round.\n *\n * Emits the `GlobalProposalCreated` event.\n *\n */\n function _proposeGlobalStruct(\n GlobalProposal.GlobalProposalDetail memory _globalProposal,\n address _roninTrustedOrganizationContract,\n address _gatewayContract,\n address _creator\n ) internal virtual returns (Proposal.ProposalDetail memory _proposal, uint256 _round) {\n _proposal = _globalProposal.into_proposal_detail(_roninTrustedOrganizationContract, _gatewayContract);\n _proposal.validate(_proposalExpiryDuration);\n\n bytes32 _proposalHash = _proposal.hash();\n _round = _createVotingRound(0, _proposalHash, _globalProposal.expiryTimestamp);\n require(_round == _proposal.nonce, \"CoreGovernance: invalid proposal nonce\");\n emit GlobalProposalCreated(_round, _proposalHash, _proposal, _globalProposal.hash(), _globalProposal, _creator);\n }\n\n /**\n * @dev Casts vote for the proposal with data and returns whether the voting is done.\n *\n * Requirements:\n * - The proposal nonce is equal to the round.\n * - The vote is not finalized.\n * - The voter has not voted for the round.\n *\n * Emits the `ProposalVoted` event. Emits the `ProposalApproved`, `ProposalExecuted` or `ProposalRejected` once the\n * proposal is approved, executed or rejected.\n *\n */\n function _castVote(\n Proposal.ProposalDetail memory _proposal,\n Ballot.VoteType _support,\n uint256 _minimumForVoteWeight,\n uint256 _minimumAgainstVoteWeight,\n address _voter,\n Signature memory _signature,\n uint256 _voterWeight\n ) internal virtual returns (bool _done) {\n uint256 _chainId = _proposal.chainId;\n uint256 _round = _proposal.nonce;\n ProposalVote storage _vote = vote[_chainId][_round];\n\n if (_tryDeleteExpiredVotingRound(_vote)) {\n return true;\n }\n\n require(round[_proposal.chainId] == _round, \"CoreGovernance: query for invalid proposal nonce\");\n require(_vote.status == VoteStatus.Pending, \"CoreGovernance: the vote is finalized\");\n if (_voted(_vote, _voter)) {\n revert(string(abi.encodePacked(\"CoreGovernance: \", Strings.toHexString(uint160(_voter), 20), \" already voted\")));\n }\n\n _vote.sig[_voter] = _signature;\n emit ProposalVoted(_vote.hash, _voter, _support, _voterWeight);\n\n uint256 _forVoteWeight;\n uint256 _againstVoteWeight;\n if (_support == Ballot.VoteType.For) {\n _vote.forVoteds.push(_voter);\n _forVoteWeight = _vote.forVoteWeight += _voterWeight;\n } else if (_support == Ballot.VoteType.Against) {\n _vote.againstVoteds.push(_voter);\n _againstVoteWeight = _vote.againstVoteWeight += _voterWeight;\n } else {\n revert(\"CoreGovernance: unsupported vote type\");\n }\n\n if (_forVoteWeight >= _minimumForVoteWeight) {\n _done = true;\n _vote.status = VoteStatus.Approved;\n emit ProposalApproved(_vote.hash);\n _tryExecute(_vote, _proposal);\n } else if (_againstVoteWeight >= _minimumAgainstVoteWeight) {\n _done = true;\n _vote.status = VoteStatus.Rejected;\n emit ProposalRejected(_vote.hash);\n }\n }\n\n /**\n * @dev Delete the expired proposal by its chainId and nonce, without creating a new proposal.\n */\n function _deleteExpiredVotingRound(uint256 _chainId, uint256 _round) internal {\n ProposalVote storage _vote = vote[_chainId][_round];\n _tryDeleteExpiredVotingRound(_vote);\n }\n\n /**\n * @dev When the contract is on Ronin chain, checks whether the proposal is expired and delete it if is expired.\n */\n function _tryDeleteExpiredVotingRound(ProposalVote storage _proposalVote) private returns (bool _isExpired) {\n _isExpired =\n _getChainType() == ChainType.RoninChain &&\n _proposalVote.status == VoteStatus.Pending &&\n _proposalVote.expiryTimestamp <= block.timestamp;\n\n if (_isExpired) {\n emit ProposalExpired(_proposalVote.hash);\n\n for (uint256 _i; _i < _proposalVote.forVoteds.length; _i++) {\n delete _proposalVote.sig[_proposalVote.forVoteds[_i]];\n }\n for (uint256 _i; _i < _proposalVote.againstVoteds.length; _i++) {\n delete _proposalVote.sig[_proposalVote.againstVoteds[_i]];\n }\n delete _proposalVote.status;\n delete _proposalVote.hash;\n delete _proposalVote.againstVoteWeight;\n delete _proposalVote.forVoteWeight;\n delete _proposalVote.forVoteds;\n delete _proposalVote.againstVoteds;\n delete _proposalVote.expiryTimestamp;\n }\n }\n\n /**\n * @dev Executes the proposal and update the vote status once the proposal is executable.\n */\n function _tryExecute(ProposalVote storage _vote, Proposal.ProposalDetail memory _proposal) internal {\n if (_proposal.executable()) {\n _vote.status = VoteStatus.Executed;\n (bool[] memory _successCalls, bytes[] memory _returnDatas) = _proposal.execute();\n emit ProposalExecuted(_vote.hash, _successCalls, _returnDatas);\n }\n }\n\n /**\n * @dev Sets the expiry duration for a new proposal.\n */\n function _setProposalExpiryDuration(uint256 _expiryDuration) internal {\n _proposalExpiryDuration = _expiryDuration;\n }\n\n /**\n * @dev Returns whether the voter casted for the proposal.\n */\n function _voted(ProposalVote storage _vote, address _voter) internal view returns (bool) {\n return _vote.sig[_voter].r != 0;\n }\n\n /**\n * @dev Returns the expiry duration for a new proposal.\n */\n function _getProposalExpiryDuration() internal view returns (uint256) {\n return _proposalExpiryDuration;\n }\n\n /**\n * @dev Returns total weight from validators.\n */\n function _getTotalWeights() internal view virtual returns (uint256);\n\n /**\n * @dev Returns minimum vote to pass a proposal.\n */\n function _getMinimumVoteWeight() internal view virtual returns (uint256);\n\n /**\n * @dev Returns current context is running on whether Ronin chain or on mainchain.\n */\n function _getChainType() internal view virtual returns (ChainType);\n}\n" + }, + "contracts/libraries/Proposal.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nlibrary Proposal {\n struct ProposalDetail {\n // Nonce to make sure proposals are executed in order\n uint256 nonce;\n // Value 0: all chain should run this proposal\n // Other values: only specifc chain has to execute\n uint256 chainId;\n uint256 expiryTimestamp;\n address[] targets;\n uint256[] values;\n bytes[] calldatas;\n uint256[] gasAmounts;\n }\n\n // keccak256(\"ProposalDetail(uint256 nonce,uint256 chainId,uint256 expiryTimestamp,address[] targets,uint256[] values,bytes[] calldatas,uint256[] gasAmounts)\");\n bytes32 public constant TYPE_HASH = 0xd051578048e6ff0bbc9fca3b65a42088dbde10f36ca841de566711087ad9b08a;\n\n /**\n * @dev Validates the proposal.\n */\n function validate(ProposalDetail memory _proposal, uint256 _maxExpiryDuration) internal view {\n require(\n _proposal.targets.length > 0 &&\n _proposal.targets.length == _proposal.values.length &&\n _proposal.targets.length == _proposal.calldatas.length &&\n _proposal.targets.length == _proposal.gasAmounts.length,\n \"Proposal: invalid array length\"\n );\n require(_proposal.expiryTimestamp <= block.timestamp + _maxExpiryDuration, \"Proposal: invalid expiry timestamp\");\n }\n\n /**\n * @dev Returns struct hash of the proposal.\n */\n function hash(ProposalDetail memory _proposal) internal pure returns (bytes32) {\n bytes32 _targetsHash;\n bytes32 _valuesHash;\n bytes32 _calldatasHash;\n bytes32 _gasAmountsHash;\n\n uint256[] memory _values = _proposal.values;\n address[] memory _targets = _proposal.targets;\n bytes32[] memory _calldataHashList = new bytes32[](_proposal.calldatas.length);\n uint256[] memory _gasAmounts = _proposal.gasAmounts;\n\n for (uint256 _i; _i < _calldataHashList.length; _i++) {\n _calldataHashList[_i] = keccak256(_proposal.calldatas[_i]);\n }\n\n assembly {\n _targetsHash := keccak256(add(_targets, 32), mul(mload(_targets), 32))\n _valuesHash := keccak256(add(_values, 32), mul(mload(_values), 32))\n _calldatasHash := keccak256(add(_calldataHashList, 32), mul(mload(_calldataHashList), 32))\n _gasAmountsHash := keccak256(add(_gasAmounts, 32), mul(mload(_gasAmounts), 32))\n }\n\n return\n keccak256(\n abi.encode(\n TYPE_HASH,\n _proposal.nonce,\n _proposal.chainId,\n _proposal.expiryTimestamp,\n _targetsHash,\n _valuesHash,\n _calldatasHash,\n _gasAmountsHash\n )\n );\n }\n\n /**\n * @dev Returns whether the proposal is executable for the current chain.\n *\n * @notice Does not check whether the call result is successful or not. Please use `execute` instead.\n *\n */\n function executable(ProposalDetail memory _proposal) internal view returns (bool _result) {\n return _proposal.chainId == 0 || _proposal.chainId == block.chainid;\n }\n\n /**\n * @dev Executes the proposal.\n */\n function execute(ProposalDetail memory _proposal)\n internal\n returns (bool[] memory _successCalls, bytes[] memory _returnDatas)\n {\n require(executable(_proposal), \"Proposal: query for invalid chainId\");\n _successCalls = new bool[](_proposal.targets.length);\n _returnDatas = new bytes[](_proposal.targets.length);\n for (uint256 _i = 0; _i < _proposal.targets.length; ++_i) {\n require(gasleft() > _proposal.gasAmounts[_i], \"Proposal: insufficient gas\");\n\n (_successCalls[_i], _returnDatas[_i]) = _proposal.targets[_i].call{\n value: _proposal.values[_i],\n gas: _proposal.gasAmounts[_i]\n }(_proposal.calldatas[_i]);\n }\n }\n}\n" + }, + "contracts/libraries/GlobalProposal.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./Proposal.sol\";\n\nlibrary GlobalProposal {\n enum TargetOption {\n RoninTrustedOrganizationContract,\n GatewayContract\n }\n\n struct GlobalProposalDetail {\n // Nonce to make sure proposals are executed in order\n uint256 nonce;\n uint256 expiryTimestamp;\n TargetOption[] targetOptions;\n uint256[] values;\n bytes[] calldatas;\n uint256[] gasAmounts;\n }\n\n // keccak256(\"GlobalProposalDetail(uint256 nonce,uint256 expiryTimestamp,uint8[] targetOptions,uint256[] values,bytes[] calldatas,uint256[] gasAmounts)\");\n bytes32 public constant TYPE_HASH = 0x1463f426c05aff2c1a7a0957a71c9898bc8b47142540538e79ee25ee91141350;\n\n /**\n * @dev Returns struct hash of the proposal.\n */\n function hash(GlobalProposalDetail memory _proposal) internal pure returns (bytes32) {\n bytes32 _targetsHash;\n bytes32 _valuesHash;\n bytes32 _calldatasHash;\n bytes32 _gasAmountsHash;\n\n uint256[] memory _values = _proposal.values;\n TargetOption[] memory _targets = _proposal.targetOptions;\n bytes32[] memory _calldataHashList = new bytes32[](_proposal.calldatas.length);\n uint256[] memory _gasAmounts = _proposal.gasAmounts;\n\n for (uint256 _i; _i < _calldataHashList.length; _i++) {\n _calldataHashList[_i] = keccak256(_proposal.calldatas[_i]);\n }\n\n assembly {\n _targetsHash := keccak256(add(_targets, 32), mul(mload(_targets), 32))\n _valuesHash := keccak256(add(_values, 32), mul(mload(_values), 32))\n _calldatasHash := keccak256(add(_calldataHashList, 32), mul(mload(_calldataHashList), 32))\n _gasAmountsHash := keccak256(add(_gasAmounts, 32), mul(mload(_gasAmounts), 32))\n }\n\n return\n keccak256(\n abi.encode(\n TYPE_HASH,\n _proposal.nonce,\n _proposal.expiryTimestamp,\n _targetsHash,\n _valuesHash,\n _calldatasHash,\n _gasAmountsHash\n )\n );\n }\n\n /**\n * @dev Converts into the normal proposal.\n */\n function into_proposal_detail(\n GlobalProposalDetail memory _proposal,\n address _roninTrustedOrganizationContract,\n address _gatewayContract\n ) internal pure returns (Proposal.ProposalDetail memory _detail) {\n _detail.nonce = _proposal.nonce;\n _detail.expiryTimestamp = _proposal.expiryTimestamp;\n _detail.chainId = 0;\n _detail.targets = new address[](_proposal.targetOptions.length);\n _detail.values = _proposal.values;\n _detail.calldatas = _proposal.calldatas;\n _detail.gasAmounts = _proposal.gasAmounts;\n\n for (uint256 _i; _i < _proposal.targetOptions.length; _i++) {\n if (_proposal.targetOptions[_i] == TargetOption.GatewayContract) {\n _detail.targets[_i] = _gatewayContract;\n } else if (_proposal.targetOptions[_i] == TargetOption.RoninTrustedOrganizationContract) {\n _detail.targets[_i] = _roninTrustedOrganizationContract;\n } else {\n revert(\"GlobalProposal: unsupported target\");\n }\n }\n }\n}\n" + }, + "contracts/libraries/Ballot.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\nlibrary Ballot {\n using ECDSA for bytes32;\n\n enum VoteType {\n For,\n Against\n }\n\n // keccak256(\"Ballot(bytes32 proposalHash,uint8 support)\");\n bytes32 public constant BALLOT_TYPEHASH = 0xd900570327c4c0df8dd6bdd522b7da7e39145dd049d2fd4602276adcd511e3c2;\n\n function hash(bytes32 _proposalHash, VoteType _support) internal pure returns (bytes32) {\n return keccak256(abi.encode(BALLOT_TYPEHASH, _proposalHash, _support));\n }\n}\n" + }, + "contracts/interfaces/consumers/ChainTypeConsumer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ChainTypeConsumer {\n enum ChainType {\n RoninChain,\n Mainchain\n }\n}\n" + }, + "contracts/interfaces/consumers/SignatureConsumer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface SignatureConsumer {\n struct Signature {\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n}\n" + }, + "contracts/ronin/RoninGovernanceAdmin.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../extensions/isolated-governance/bridge-operator-governance/BOsGovernanceProposal.sol\";\nimport \"../extensions/sequential-governance/GovernanceProposal.sol\";\nimport \"../extensions/GovernanceAdmin.sol\";\nimport \"../interfaces/IBridge.sol\";\n\ncontract RoninGovernanceAdmin is GovernanceAdmin, GovernanceProposal, BOsGovernanceProposal {\n /// @dev Emitted when the bridge operators are approved.\n event BridgeOperatorsApproved(uint256 _period, address[] _operators);\n\n modifier onlyGovernor() {\n require(_getWeight(msg.sender) > 0, \"GovernanceAdmin: sender is not governor\");\n _;\n }\n\n constructor(\n address _roninTrustedOrganizationContract,\n address _bridgeContract,\n uint256 _proposalExpiryDuration\n ) GovernanceAdmin(_roninTrustedOrganizationContract, _bridgeContract, _proposalExpiryDuration) {}\n\n /**\n * @dev Returns the voted signatures for the proposals.\n *\n */\n function getProposalSignatures(uint256 _chainId, uint256 _round)\n external\n view\n returns (Ballot.VoteType[] memory _supports, Signature[] memory _signatures)\n {\n ProposalVote storage _vote = vote[_chainId][_round];\n\n uint256 _forLength = _vote.forVoteds.length;\n uint256 _againstLength = _vote.againstVoteds.length;\n uint256 _voterLength = _forLength + _againstLength;\n\n _supports = new Ballot.VoteType[](_voterLength);\n _signatures = new Signature[](_voterLength);\n for (uint256 _i; _i < _forLength; _i++) {\n _supports[_i] = Ballot.VoteType.For;\n _signatures[_i] = vote[_chainId][_round].sig[_vote.forVoteds[_i]];\n }\n for (uint256 _i; _i < _againstLength; _i++) {\n _supports[_i + _forLength] = Ballot.VoteType.Against;\n _signatures[_i + _forLength] = vote[_chainId][_round].sig[_vote.againstVoteds[_i]];\n }\n }\n\n /**\n * @dev Returns the voted signatures for bridge operators at a specific period.\n *\n * Note: Does not verify whether the voter casted vote for the proposal and the returned signature can be empty.\n * Please consider filtering for empty signatures after calling this function.\n *\n */\n function getBridgeOperatorVotingSignatures(uint256 _period, address[] calldata _voters)\n external\n view\n returns (Signature[] memory _signatures)\n {\n _signatures = new Signature[](_voters.length);\n for (uint256 _i; _i < _voters.length; _i++) {\n _signatures[_i] = _votingSig[_period][_voters[_i]];\n }\n }\n\n /**\n * @dev Returns whether the voter `_voter` casted vote for the proposal.\n */\n function proposalVoted(\n uint256 _chainId,\n uint256 _round,\n address _voter\n ) external view returns (bool) {\n return _voted(vote[_chainId][_round], _voter);\n }\n\n /**\n * @dev Returns whether the voter `_voter` casted vote for bridge operators at a specific period.\n */\n function bridgeOperatorsVoted(uint256 _period, address _voter) external view returns (bool) {\n return _voted(_vote[_period], _voter);\n }\n\n /**\n * @dev See `CoreGovernance-_proposeProposal`.\n *\n * Requirements:\n * - The method caller is governor.\n *\n */\n function propose(\n uint256 _chainId,\n uint256 _expiryTimestamp,\n address[] calldata _targets,\n uint256[] calldata _values,\n bytes[] calldata _calldatas,\n uint256[] calldata _gasAmounts\n ) external onlyGovernor {\n _proposeProposal(_chainId, _expiryTimestamp, _targets, _values, _calldatas, _gasAmounts, msg.sender);\n }\n\n /**\n * @dev See `GovernanceProposal-_proposeProposalStructAndCastVotes`.\n *\n * Requirements:\n * - The method caller is governor.\n *\n */\n function proposeProposalStructAndCastVotes(\n Proposal.ProposalDetail calldata _proposal,\n Ballot.VoteType[] calldata _supports,\n Signature[] calldata _signatures\n ) external onlyGovernor {\n _proposeProposalStructAndCastVotes(_proposal, _supports, _signatures, DOMAIN_SEPARATOR, msg.sender);\n }\n\n /**\n * @dev See `GovernanceProposal-_castProposalBySignatures`.\n */\n function castProposalBySignatures(\n Proposal.ProposalDetail calldata _proposal,\n Ballot.VoteType[] calldata _supports,\n Signature[] calldata _signatures\n ) external {\n _castProposalBySignatures(_proposal, _supports, _signatures, DOMAIN_SEPARATOR);\n }\n\n /**\n * @dev See `CoreGovernance-_proposeGlobal`.\n *\n * Requirements:\n * - The method caller is governor.\n *\n */\n function proposeGlobal(\n uint256 _expiryTimestamp,\n GlobalProposal.TargetOption[] calldata _targetOptions,\n uint256[] calldata _values,\n bytes[] calldata _calldatas,\n uint256[] calldata _gasAmounts\n ) external onlyGovernor {\n _proposeGlobal(\n _expiryTimestamp,\n _targetOptions,\n _values,\n _calldatas,\n _gasAmounts,\n roninTrustedOrganizationContract(),\n bridgeContract(),\n msg.sender\n );\n }\n\n /**\n * @dev See `GovernanceProposal-_proposeGlobalProposalStructAndCastVotes`.\n *\n * Requirements:\n * - The method caller is governor.\n *\n */\n function proposeGlobalProposalStructAndCastVotes(\n GlobalProposal.GlobalProposalDetail calldata _globalProposal,\n Ballot.VoteType[] calldata _supports,\n Signature[] calldata _signatures\n ) external onlyGovernor {\n _proposeGlobalProposalStructAndCastVotes(\n _globalProposal,\n _supports,\n _signatures,\n DOMAIN_SEPARATOR,\n roninTrustedOrganizationContract(),\n bridgeContract(),\n msg.sender\n );\n }\n\n /**\n * @dev See `GovernanceProposal-_castGlobalProposalBySignatures`.\n */\n function castGlobalProposalBySignatures(\n GlobalProposal.GlobalProposalDetail calldata _globalProposal,\n Ballot.VoteType[] calldata _supports,\n Signature[] calldata _signatures\n ) external {\n _castGlobalProposalBySignatures(\n _globalProposal,\n _supports,\n _signatures,\n DOMAIN_SEPARATOR,\n roninTrustedOrganizationContract(),\n bridgeContract()\n );\n }\n\n /**\n * @dev See `CoreGovernance-_deleteExpiredProposal`\n */\n function deleteExpired(uint256 chainId, uint256 round) external {\n _deleteExpiredVotingRound(chainId, round);\n }\n\n /**\n * @dev See `BOsGovernanceProposal-_castVotesBySignatures`.\n */\n function voteBridgeOperatorsBySignatures(\n uint256 _period,\n address[] calldata _operators,\n Signature[] calldata _signatures\n ) external {\n _castVotesBySignatures(_operators, _signatures, _period, _getMinimumVoteWeight(), DOMAIN_SEPARATOR);\n IsolatedVote storage _v = _vote[_period];\n if (_v.status == VoteStatus.Approved) {\n _lastSyncedPeriod = _period;\n emit BridgeOperatorsApproved(_period, _operators);\n _v.status = VoteStatus.Executed;\n }\n }\n\n /**\n * @inheritdoc GovernanceProposal\n */\n function _getWeight(address _governor) internal view virtual override returns (uint256) {\n (bool _success, bytes memory _returndata) = roninTrustedOrganizationContract().staticcall(\n abi.encodeWithSelector(\n // TransparentUpgradeableProxyV2.functionDelegateCall.selector,\n 0x4bb5274a,\n abi.encodeWithSelector(IRoninTrustedOrganization.getGovernorWeight.selector, _governor)\n )\n );\n require(_success, \"GovernanceAdmin: proxy call `getGovernorWeight(address)` failed\");\n return abi.decode(_returndata, (uint256));\n }\n\n /**\n * @inheritdoc BOsGovernanceProposal\n */\n function _getBridgeVoterWeight(address _governor) internal view virtual override returns (uint256) {\n (bool _success, bytes memory _returndata) = roninTrustedOrganizationContract().staticcall(\n abi.encodeWithSelector(\n // TransparentUpgradeableProxyV2.functionDelegateCall.selector,\n 0x4bb5274a,\n abi.encodeWithSelector(IRoninTrustedOrganization.getBridgeVoterWeight.selector, _governor)\n )\n );\n require(_success, \"GovernanceAdmin: proxy call `getBridgeVoterWeight(address)` failed\");\n return abi.decode(_returndata, (uint256));\n }\n\n /**\n * @dev See {CoreGovernance-_getChainType}\n */\n function _getChainType() internal pure override returns (ChainType) {\n return ChainType.RoninChain;\n }\n}\n" + }, + "contracts/extensions/isolated-governance/bridge-operator-governance/BOsGovernanceProposal.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../../../extensions/isolated-governance/IsolatedGovernance.sol\";\nimport \"../../../interfaces/consumers/SignatureConsumer.sol\";\nimport \"../../../libraries/BridgeOperatorsBallot.sol\";\nimport \"../../../interfaces/IRoninGovernanceAdmin.sol\";\n\nabstract contract BOsGovernanceProposal is SignatureConsumer, IsolatedGovernance, IRoninGovernanceAdmin {\n /// @dev The last period that the brige operators synced.\n uint256 internal _lastSyncedPeriod;\n /// @dev Mapping from period index => bridge operators vote\n mapping(uint256 => IsolatedVote) internal _vote;\n\n /// @dev Mapping from bridge voter address => last block that the address voted\n mapping(address => uint256) internal _lastVotedBlock;\n /// @dev Mapping from period => voter => signatures\n mapping(uint256 => mapping(address => Signature)) internal _votingSig;\n\n /**\n * @inheritdoc IRoninGovernanceAdmin\n */\n function lastVotedBlock(address _bridgeVoter) external view returns (uint256) {\n return _lastVotedBlock[_bridgeVoter];\n }\n\n /**\n * @dev Votes for a set of bridge operators by signatures.\n *\n * Requirements:\n * - The period of voting is larger than the last synced period.\n * - The arrays are not empty.\n * - The signature signers are in order.\n *\n */\n function _castVotesBySignatures(\n address[] calldata _operators,\n Signature[] calldata _signatures,\n uint256 _period,\n uint256 _minimumVoteWeight,\n bytes32 _domainSeperator\n ) internal {\n require(_period >= _lastSyncedPeriod, \"BOsGovernanceProposal: query for outdated period\");\n require(_operators.length > 0 && _signatures.length > 0, \"BOsGovernanceProposal: invalid array length\");\n\n Signature memory _sig;\n address _signer;\n address _lastSigner;\n bytes32 _hash = BridgeOperatorsBallot.hash(_period, _operators);\n bytes32 _digest = ECDSA.toTypedDataHash(_domainSeperator, _hash);\n IsolatedVote storage _v = _vote[_period];\n bool _hasValidVotes;\n\n for (uint256 _i = 0; _i < _signatures.length; _i++) {\n _sig = _signatures[_i];\n _signer = ECDSA.recover(_digest, _sig.v, _sig.r, _sig.s);\n require(_lastSigner < _signer, \"BOsGovernanceProposal: invalid order\");\n _lastSigner = _signer;\n\n uint256 _weight = _getBridgeVoterWeight(_signer);\n if (_weight > 0) {\n _hasValidVotes = true;\n _lastVotedBlock[_signer] = block.number;\n _votingSig[_period][_signer] = _sig;\n if (_castVote(_v, _signer, _weight, _minimumVoteWeight, _hash) == VoteStatus.Approved) {\n return;\n }\n }\n }\n\n require(_hasValidVotes, \"BOsGovernanceProposal: invalid signatures\");\n }\n\n /**\n * @dev Returns the weight of a bridge voter.\n */\n function _getBridgeVoterWeight(address _bridgeVoter) internal view virtual returns (uint256);\n}\n" + }, + "contracts/extensions/sequential-governance/GovernanceProposal.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./CoreGovernance.sol\";\n\nabstract contract GovernanceProposal is CoreGovernance {\n using Proposal for Proposal.ProposalDetail;\n using GlobalProposal for GlobalProposal.GlobalProposalDetail;\n\n /**\n * @dev Casts votes by signatures.\n *\n * Note: This method does not verify the proposal hash with the vote hash. Please consider checking it before.\n *\n */\n function _castVotesBySignatures(\n Proposal.ProposalDetail memory _proposal,\n Ballot.VoteType[] calldata _supports,\n Signature[] calldata _signatures,\n bytes32 _forDigest,\n bytes32 _againstDigest\n ) internal {\n require(_supports.length > 0 && _supports.length == _signatures.length, \"GovernanceProposal: invalid array length\");\n uint256 _minimumForVoteWeight = _getMinimumVoteWeight();\n uint256 _minimumAgainstVoteWeight = _getTotalWeights() - _minimumForVoteWeight + 1;\n\n address _lastSigner;\n address _signer;\n Signature memory _sig;\n bool _hasValidVotes;\n for (uint256 _i; _i < _signatures.length; _i++) {\n _sig = _signatures[_i];\n\n if (_supports[_i] == Ballot.VoteType.For) {\n _signer = ECDSA.recover(_forDigest, _sig.v, _sig.r, _sig.s);\n } else if (_supports[_i] == Ballot.VoteType.Against) {\n _signer = ECDSA.recover(_againstDigest, _sig.v, _sig.r, _sig.s);\n } else {\n revert(\"GovernanceProposal: query for unsupported vote type\");\n }\n\n require(_lastSigner < _signer, \"GovernanceProposal: invalid order\");\n _lastSigner = _signer;\n\n uint256 _weight = _getWeight(_signer);\n if (_weight > 0) {\n _hasValidVotes = true;\n if (\n _castVote(_proposal, _supports[_i], _minimumForVoteWeight, _minimumAgainstVoteWeight, _signer, _sig, _weight)\n ) {\n return;\n }\n }\n }\n\n require(_hasValidVotes, \"GovernanceProposal: invalid signatures\");\n }\n\n /**\n * @dev Proposes a proposal struct and casts votes by signature.\n */\n function _proposeProposalStructAndCastVotes(\n Proposal.ProposalDetail calldata _proposal,\n Ballot.VoteType[] calldata _supports,\n Signature[] calldata _signatures,\n bytes32 _domainSeparator,\n address _creator\n ) internal {\n _proposeProposalStruct(_proposal, _creator);\n bytes32 _proposalHash = _proposal.hash();\n _castVotesBySignatures(\n _proposal,\n _supports,\n _signatures,\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_proposalHash, Ballot.VoteType.For)),\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_proposalHash, Ballot.VoteType.Against))\n );\n }\n\n /**\n * @dev Proposes a proposal struct and casts votes by signature.\n */\n function _castProposalBySignatures(\n Proposal.ProposalDetail calldata _proposal,\n Ballot.VoteType[] calldata _supports,\n Signature[] calldata _signatures,\n bytes32 _domainSeparator\n ) internal {\n bytes32 _proposalHash = _proposal.hash();\n require(\n vote[_proposal.chainId][_proposal.nonce].hash == _proposalHash,\n \"GovernanceAdmin: cast vote for invalid proposal\"\n );\n _castVotesBySignatures(\n _proposal,\n _supports,\n _signatures,\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_proposalHash, Ballot.VoteType.For)),\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_proposalHash, Ballot.VoteType.Against))\n );\n }\n\n /**\n * @dev Proposes and votes by signature.\n */\n function _proposeGlobalProposalStructAndCastVotes(\n GlobalProposal.GlobalProposalDetail calldata _globalProposal,\n Ballot.VoteType[] calldata _supports,\n Signature[] calldata _signatures,\n bytes32 _domainSeparator,\n address _roninTrustedOrganizationContract,\n address _gatewayContract,\n address _creator\n ) internal returns (Proposal.ProposalDetail memory _proposal) {\n (_proposal, ) = _proposeGlobalStruct(\n _globalProposal,\n _roninTrustedOrganizationContract,\n _gatewayContract,\n _creator\n );\n bytes32 _globalProposalHash = _globalProposal.hash();\n _castVotesBySignatures(\n _proposal,\n _supports,\n _signatures,\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_globalProposalHash, Ballot.VoteType.For)),\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_globalProposalHash, Ballot.VoteType.Against))\n );\n }\n\n /**\n * @dev Proposes a global proposal struct and casts votes by signature.\n */\n function _castGlobalProposalBySignatures(\n GlobalProposal.GlobalProposalDetail calldata _globalProposal,\n Ballot.VoteType[] calldata _supports,\n Signature[] calldata _signatures,\n bytes32 _domainSeparator,\n address _roninTrustedOrganizationContract,\n address _gatewayContract\n ) internal {\n Proposal.ProposalDetail memory _proposal = _globalProposal.into_proposal_detail(\n _roninTrustedOrganizationContract,\n _gatewayContract\n );\n bytes32 _globalProposalHash = _globalProposal.hash();\n require(vote[0][_proposal.nonce].hash == _proposal.hash(), \"GovernanceAdmin: cast vote for invalid proposal\");\n _castVotesBySignatures(\n _proposal,\n _supports,\n _signatures,\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_globalProposalHash, Ballot.VoteType.For)),\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_globalProposalHash, Ballot.VoteType.Against))\n );\n }\n\n /**\n * @dev Returns the weight of a governor.\n */\n function _getWeight(address _governor) internal view virtual returns (uint256);\n}\n" + }, + "contracts/libraries/BridgeOperatorsBallot.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport \"../interfaces/consumers/WeightedAddressConsumer.sol\";\n\nlibrary BridgeOperatorsBallot {\n // keccak256(\"BridgeOperatorsBallot(uint256 period,address[] operators)\");\n bytes32 public constant BRIDGE_OPERATORS_BALLOT_TYPEHASH =\n 0xeea5e3908ac28cbdbbce8853e49444c558a0a03597e98ef19e6ff86162ed9ae3;\n\n /**\n * @dev Returns hash of the ballot.\n */\n function hash(uint256 _period, address[] memory _operators) internal pure returns (bytes32) {\n bytes32 _operatorsHash;\n assembly {\n _operatorsHash := keccak256(add(_operators, 32), mul(mload(_operators), 32))\n }\n\n return keccak256(abi.encode(BRIDGE_OPERATORS_BALLOT_TYPEHASH, _period, _operatorsHash));\n }\n}\n" + }, + "contracts/interfaces/IRoninGovernanceAdmin.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IRoninGovernanceAdmin {\n /**\n * @dev Returns the last voted block of the bridge voter.\n */\n function lastVotedBlock(address _bridgeVoter) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/consumers/WeightedAddressConsumer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface WeightedAddressConsumer {\n struct WeightedAddress {\n address addr;\n uint256 weight;\n }\n}\n" + }, + "contracts/mocks/MockBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol\";\nimport \"../interfaces/IBridge.sol\";\n\ncontract MockBridge is IBridge {\n /// @dev Mapping from validator address => last block that the bridge operator is added\n mapping(address => uint256) public bridgeOperatorAddedBlock;\n /// @dev Bridge operators array\n address[] public bridgeOperators;\n\n function replaceBridgeOperators(address[] calldata _list) external {\n address _addr;\n for (uint256 _i = 0; _i < _list.length; _i++) {\n _addr = _list[_i];\n if (bridgeOperatorAddedBlock[_addr] == 0) {\n bridgeOperators.push(_addr);\n }\n bridgeOperatorAddedBlock[_addr] = block.number;\n }\n\n {\n uint256 _i;\n while (_i < bridgeOperators.length) {\n _addr = bridgeOperators[_i];\n if (bridgeOperatorAddedBlock[_addr] < block.number) {\n delete bridgeOperatorAddedBlock[_addr];\n bridgeOperators[_i] = bridgeOperators[bridgeOperators.length - 1];\n bridgeOperators.pop();\n continue;\n }\n _i++;\n }\n }\n }\n\n function getBridgeOperators() external view override returns (address[] memory) {\n return bridgeOperators;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/presets/ERC20PresetMinterPauser.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../extensions/ERC20Burnable.sol\";\nimport \"../extensions/ERC20Pausable.sol\";\nimport \"../../../access/AccessControlEnumerable.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev {ERC20} token, including:\n *\n * - ability for holders to burn (destroy) their tokens\n * - a minter role that allows for token minting (creation)\n * - a pauser role that allows to stop all token transfers\n *\n * This contract uses {AccessControl} to lock permissioned functions using the\n * different roles - head to its documentation for details.\n *\n * The account that deploys the contract will be granted the minter and pauser\n * roles, as well as the default admin role, which will let it grant both minter\n * and pauser roles to other accounts.\n *\n * _Deprecated in favor of https://wizard.openzeppelin.com/[Contracts Wizard]._\n */\ncontract ERC20PresetMinterPauser is Context, AccessControlEnumerable, ERC20Burnable, ERC20Pausable {\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant PAUSER_ROLE = keccak256(\"PAUSER_ROLE\");\n\n /**\n * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the\n * account that deploys the contract.\n *\n * See {ERC20-constructor}.\n */\n constructor(string memory name, string memory symbol) ERC20(name, symbol) {\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\n\n _setupRole(MINTER_ROLE, _msgSender());\n _setupRole(PAUSER_ROLE, _msgSender());\n }\n\n /**\n * @dev Creates `amount` new tokens for `to`.\n *\n * See {ERC20-_mint}.\n *\n * Requirements:\n *\n * - the caller must have the `MINTER_ROLE`.\n */\n function mint(address to, uint256 amount) public virtual {\n require(hasRole(MINTER_ROLE, _msgSender()), \"ERC20PresetMinterPauser: must have minter role to mint\");\n _mint(to, amount);\n }\n\n /**\n * @dev Pauses all token transfers.\n *\n * See {ERC20Pausable} and {Pausable-_pause}.\n *\n * Requirements:\n *\n * - the caller must have the `PAUSER_ROLE`.\n */\n function pause() public virtual {\n require(hasRole(PAUSER_ROLE, _msgSender()), \"ERC20PresetMinterPauser: must have pauser role to pause\");\n _pause();\n }\n\n /**\n * @dev Unpauses all token transfers.\n *\n * See {ERC20Pausable} and {Pausable-_unpause}.\n *\n * Requirements:\n *\n * - the caller must have the `PAUSER_ROLE`.\n */\n function unpause() public virtual {\n require(hasRole(PAUSER_ROLE, _msgSender()), \"ERC20PresetMinterPauser: must have pauser role to unpause\");\n _unpause();\n }\n\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override(ERC20, ERC20Pausable) {\n super._beforeTokenTransfer(from, to, amount);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../security/Pausable.sol\";\n\n/**\n * @dev ERC20 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC20Pausable is ERC20, Pausable {\n /**\n * @dev See {ERC20-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n require(!paused(), \"ERC20Pausable: token transfer while paused\");\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"../../access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(\n address _logic,\n address admin_,\n bytes memory _data\n ) payable ERC1967Proxy(_logic, _data) {\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "contracts/ronin/validator/RoninValidatorSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport \"../../interfaces/validator/IRoninValidatorSet.sol\";\nimport \"./CoinbaseExecution.sol\";\nimport \"./SlashingExecution.sol\";\n\ncontract RoninValidatorSet is Initializable, CoinbaseExecution, SlashingExecution {\n constructor() {\n _disableInitializers();\n }\n\n fallback() external payable {\n _fallback();\n }\n\n receive() external payable {\n _fallback();\n }\n\n /**\n * @dev Initializes the contract storage.\n */\n function initialize(\n address __slashIndicatorContract,\n address __stakingContract,\n address __stakingVestingContract,\n address __maintenanceContract,\n address __roninTrustedOrganizationContract,\n address __bridgeTrackingContract,\n uint256 __maxValidatorNumber,\n uint256 __maxValidatorCandidate,\n uint256 __maxPrioritizedValidatorNumber,\n uint256 __minEffectiveDaysOnwards,\n uint256 __numberOfBlocksInEpoch\n ) external initializer {\n _setSlashIndicatorContract(__slashIndicatorContract);\n _setStakingContract(__stakingContract);\n _setStakingVestingContract(__stakingVestingContract);\n _setMaintenanceContract(__maintenanceContract);\n _setBridgeTrackingContract(__bridgeTrackingContract);\n _setRoninTrustedOrganizationContract(__roninTrustedOrganizationContract);\n _setMaxValidatorNumber(__maxValidatorNumber);\n _setMaxValidatorCandidate(__maxValidatorCandidate);\n _setMaxPrioritizedValidatorNumber(__maxPrioritizedValidatorNumber);\n _setMinEffectiveDaysOnwards(__minEffectiveDaysOnwards);\n _numberOfBlocksInEpoch = __numberOfBlocksInEpoch;\n }\n\n /**\n * @dev Only receives RON from staking vesting contract (for topping up bonus), and from staking contract (for transferring\n * deducting amount when slash).\n */\n function _fallback() internal view {\n require(\n msg.sender == stakingVestingContract() || msg.sender == stakingContract(),\n \"RoninValidatorSet: only receives RON from staking vesting contract or staking contract\"\n );\n }\n\n /**\n * @dev Override `ValidatorInfoStorage-_bridgeOperatorOf`.\n */\n function _bridgeOperatorOf(address _consensusAddr)\n internal\n view\n override(CoinbaseExecution, ValidatorInfoStorage)\n returns (address)\n {\n return CoinbaseExecution._bridgeOperatorOf(_consensusAddr);\n }\n}\n" + }, + "contracts/ronin/validator/SlashingExecution.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../extensions/collections/HasSlashIndicatorContract.sol\";\nimport \"../../extensions/collections/HasStakingContract.sol\";\nimport \"../../interfaces/validator/ISlashingExecution.sol\";\nimport \"./storage-fragments/CommonStorage.sol\";\n\nabstract contract SlashingExecution is\n ISlashingExecution,\n HasSlashIndicatorContract,\n HasStakingContract,\n CommonStorage\n{\n /**\n * @inheritdoc ISlashingExecution\n */\n function execSlash(\n address _validatorAddr,\n uint256 _newJailedUntil,\n uint256 _slashAmount\n ) external override onlySlashIndicatorContract {\n uint256 _period = currentPeriod();\n _miningRewardDeprecatedAtPeriod[_validatorAddr][_period] = true;\n\n _totalDeprecatedReward += _miningReward[_validatorAddr] + _delegatingReward[_validatorAddr];\n\n delete _miningReward[_validatorAddr];\n delete _delegatingReward[_validatorAddr];\n\n if (_newJailedUntil > _jailedUntil[_validatorAddr]) {\n _jailedUntil[_validatorAddr] = _newJailedUntil;\n }\n\n if (_slashAmount > 0) {\n uint256 _actualAmount = _stakingContract.deductStakingAmount(_validatorAddr, _slashAmount);\n _totalDeprecatedReward += _actualAmount;\n }\n\n emit ValidatorPunished(_validatorAddr, _period, _jailedUntil[_validatorAddr], _slashAmount, true, false);\n }\n\n /**\n * @inheritdoc ISlashingExecution\n */\n function execBailOut(address _validatorAddr, uint256 _period) external override onlySlashIndicatorContract {\n // Note: Removing rewards of validator in `bailOut` function is not needed, since the rewards have been\n // removed previously in the `slash` function.\n _miningRewardBailoutCutOffAtPeriod[_validatorAddr][_period] = true;\n _miningRewardDeprecatedAtPeriod[_validatorAddr][_period] = false;\n _jailedUntil[_validatorAddr] = block.number - 1;\n\n emit ValidatorUnjailed(_validatorAddr, _period);\n }\n}\n" + }, + "contracts/ronin/slash-indicator/SlashBridgeVoting.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../libraries/Math.sol\";\nimport \"../../interfaces/slash-indicator/ISlashBridgeVoting.sol\";\nimport \"../../extensions/collections/HasRoninTrustedOrganizationContract.sol\";\nimport \"../../extensions/collections/HasRoninGovernanceAdminContract.sol\";\nimport \"../../extensions/collections/HasValidatorContract.sol\";\n\nabstract contract SlashBridgeVoting is\n ISlashBridgeVoting,\n HasValidatorContract,\n HasRoninTrustedOrganizationContract,\n HasRoninGovernanceAdminContract\n{\n /// @dev Mapping from validator address => period index => bridge voting slashed\n mapping(address => mapping(uint256 => bool)) internal _bridgeVotingSlashed;\n /// @dev The threshold to slash when a trusted organization does not vote for bridge operators.\n uint256 internal _bridgeVotingThreshold;\n /// @dev The amount of RON to slash bridge voting.\n uint256 internal _bridgeVotingSlashAmount;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n /**\n * @inheritdoc ISlashBridgeVoting\n */\n function slashBridgeVoting(address _consensusAddr) external {\n IRoninTrustedOrganization.TrustedOrganization memory _org = _roninTrustedOrganizationContract\n .getTrustedOrganization(_consensusAddr);\n uint256 _lastVotedBlock = Math.max(_roninGovernanceAdminContract.lastVotedBlock(_org.bridgeVoter), _org.addedBlock);\n uint256 _period = _validatorContract.currentPeriod();\n if (block.number - _lastVotedBlock > _bridgeVotingThreshold && !_bridgeVotingSlashed[_consensusAddr][_period]) {\n _bridgeVotingSlashed[_consensusAddr][_period] = true;\n emit Slashed(_consensusAddr, SlashType.BRIDGE_VOTING, _period);\n _validatorContract.execSlash(_consensusAddr, 0, _bridgeVotingSlashAmount);\n }\n }\n\n /**\n * @inheritdoc ISlashBridgeVoting\n */\n function getBridgeVotingSlashingConfigs() external view override returns (uint256, uint256) {\n return (_bridgeVotingThreshold, _bridgeVotingSlashAmount);\n }\n\n /**\n * @inheritdoc ISlashBridgeVoting\n */\n function setBridgeVotingSlashingConfigs(uint256 _threshold, uint256 _slashAmount) external override onlyAdmin {\n _setBridgeVotingSlashingConfigs(_threshold, _slashAmount);\n }\n\n /**\n * @dev See `ISlashBridgeVoting-setBridgeVotingSlashingConfigs`.\n */\n function _setBridgeVotingSlashingConfigs(uint256 _threshold, uint256 _slashAmount) internal {\n _bridgeVotingThreshold = _threshold;\n _slashAmount = _bridgeVotingSlashAmount;\n emit BridgeVotingSlashingConfigsUpdated(_threshold, _slashAmount);\n }\n}\n" + }, + "contracts/extensions/collections/HasRoninGovernanceAdminContract.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./HasProxyAdmin.sol\";\nimport \"../../interfaces/collections/IHasRoninGovernanceAdminContract.sol\";\nimport \"../../interfaces/IRoninGovernanceAdmin.sol\";\n\ncontract HasRoninGovernanceAdminContract is IHasRoninGovernanceAdminContract, HasProxyAdmin {\n IRoninGovernanceAdmin internal _roninGovernanceAdminContract;\n\n modifier onlyRoninGovernanceAdminContract() {\n require(\n roninGovernanceAdminContract() == msg.sender,\n \"HasRoninGovernanceAdminContract: method caller must be ronin governance admin contract\"\n );\n _;\n }\n\n /**\n * @inheritdoc IHasRoninGovernanceAdminContract\n */\n function roninGovernanceAdminContract() public view override returns (address) {\n return address(_roninGovernanceAdminContract);\n }\n\n /**\n * @inheritdoc IHasRoninGovernanceAdminContract\n */\n function setRoninGovernanceAdminContract(address _addr) external override onlyAdmin {\n require(_addr.code.length > 0, \"HasRoninGovernanceAdminContract: set to non-contract\");\n _setRoninGovernanceAdminContract(_addr);\n }\n\n /**\n * @dev Sets the ronin governance admin contract.\n *\n * Emits the event `RoninGovernanceAdminContractUpdated`.\n *\n */\n function _setRoninGovernanceAdminContract(address _addr) internal {\n _roninGovernanceAdminContract = IRoninGovernanceAdmin(_addr);\n emit RoninGovernanceAdminContractUpdated(_addr);\n }\n}\n" + }, + "contracts/interfaces/collections/IHasRoninGovernanceAdminContract.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\ninterface IHasRoninGovernanceAdminContract {\n /// @dev Emitted when the ronin governance admin contract is updated.\n event RoninGovernanceAdminContractUpdated(address);\n\n /**\n * @dev Returns the ronin governance admin contract.\n */\n function roninGovernanceAdminContract() external view returns (address);\n\n /**\n * @dev Sets the ronin governance admin contract.\n *\n * Requirements:\n * - The method caller is admin.\n * - The new address is a contract.\n *\n * Emits the event `RoninGovernanceAdminContractUpdated`.\n *\n */\n function setRoninGovernanceAdminContract(address) external;\n}\n" + }, + "contracts/extensions/isolated-governance/bridge-operator-governance/BOsGovernanceRelay.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../../../extensions/isolated-governance/IsolatedGovernance.sol\";\nimport \"../../../interfaces/consumers/SignatureConsumer.sol\";\nimport \"../../../libraries/BridgeOperatorsBallot.sol\";\n\nabstract contract BOsGovernanceRelay is SignatureConsumer, IsolatedGovernance {\n /// @dev The last period that the brige operators synced.\n uint256 internal _lastSyncedPeriod;\n /// @dev Mapping from period index => bridge operators vote\n mapping(uint256 => IsolatedVote) internal _vote;\n\n /**\n * @dev Relays votes by signatures.\n *\n * Requirements:\n * - The period of voting is larger than the last synced period.\n * - The arrays are not empty.\n * - The signature signers are in order.\n *\n * @notice Does not store the voter signature into storage.\n *\n */\n function _relayVotesBySignatures(\n address[] calldata _operators,\n Signature[] calldata _signatures,\n uint256 _period,\n uint256 _minimumVoteWeight,\n bytes32 _domainSeperator\n ) internal {\n require(_period > _lastSyncedPeriod, \"BOsGovernanceRelay: query for outdated period\");\n require(_operators.length > 0 && _signatures.length > 0, \"BOsGovernanceRelay: invalid array length\");\n\n Signature memory _sig;\n address[] memory _signers = new address[](_signatures.length);\n address _lastSigner;\n bytes32 _hash = BridgeOperatorsBallot.hash(_period, _operators);\n bytes32 _digest = ECDSA.toTypedDataHash(_domainSeperator, _hash);\n\n for (uint256 _i = 0; _i < _signatures.length; _i++) {\n _sig = _signatures[_i];\n _signers[_i] = ECDSA.recover(_digest, _sig.v, _sig.r, _sig.s);\n require(_lastSigner < _signers[_i], \"BOsGovernanceRelay: invalid order\");\n _lastSigner = _signers[_i];\n }\n\n IsolatedVote storage _v = _vote[_period];\n uint256 _totalVoteWeight = _sumBridgeVoterWeights(_signers);\n if (_totalVoteWeight >= _minimumVoteWeight) {\n require(_totalVoteWeight > 0, \"BOsGovernanceRelay: invalid vote weight\");\n _v.status = VoteStatus.Approved;\n _lastSyncedPeriod = _period;\n return;\n }\n\n revert(\"BOsGovernanceRelay: relay failed\");\n }\n\n /**\n * @dev Returns the weight of the governor list.\n */\n function _sumBridgeVoterWeights(address[] memory _bridgeVoters) internal view virtual returns (uint256);\n}\n" + }, + "contracts/mainchain/MainchainGovernanceAdmin.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/access/AccessControlEnumerable.sol\";\nimport \"../extensions/isolated-governance/bridge-operator-governance/BOsGovernanceRelay.sol\";\nimport \"../extensions/sequential-governance/GovernanceRelay.sol\";\nimport \"../extensions/TransparentUpgradeableProxyV2.sol\";\nimport \"../extensions/GovernanceAdmin.sol\";\nimport \"../interfaces/IBridge.sol\";\n\ncontract MainchainGovernanceAdmin is AccessControlEnumerable, GovernanceRelay, GovernanceAdmin, BOsGovernanceRelay {\n bytes32 public constant RELAYER_ROLE = keccak256(\"RELAYER_ROLE\");\n uint256 private constant DEFAULT_EXPIRY_DURATION = 1 << 255;\n\n constructor(\n address _roleSetter,\n address _roninTrustedOrganizationContract,\n address _bridgeContract,\n address[] memory _relayers\n ) GovernanceAdmin(_roninTrustedOrganizationContract, _bridgeContract, DEFAULT_EXPIRY_DURATION) {\n _setupRole(DEFAULT_ADMIN_ROLE, _roleSetter);\n for (uint256 _i; _i < _relayers.length; _i++) {\n _grantRole(RELAYER_ROLE, _relayers[_i]);\n }\n }\n\n /**\n * @dev Returns whether the voter `_voter` casted vote for the proposal.\n */\n function proposalRelayed(uint256 _chainId, uint256 _round) external view returns (bool) {\n return vote[_chainId][_round].status != VoteStatus.Pending;\n }\n\n /**\n * @dev Returns whether the voter `_voter` casted vote for bridge operators at a specific period.\n */\n function bridgeOperatorsRelayed(uint256 _period) external view returns (bool) {\n return _vote[_period].status != VoteStatus.Pending;\n }\n\n /**\n * @dev See `GovernanceRelay-_relayProposal`.\n *\n * Requirements:\n * - The method caller is relayer.\n *\n */\n function relayProposal(\n Proposal.ProposalDetail calldata _proposal,\n Ballot.VoteType[] calldata _supports,\n Signature[] calldata _signatures\n ) external onlyRole(RELAYER_ROLE) {\n _relayProposal(_proposal, _supports, _signatures, DOMAIN_SEPARATOR, msg.sender);\n }\n\n /**\n * @dev See `GovernanceRelay-_relayGlobalProposal`.\n *\n * Requirements:\n * - The method caller is relayer.\n *\n */\n function relayGlobalProposal(\n GlobalProposal.GlobalProposalDetail calldata _globalProposal,\n Ballot.VoteType[] calldata _supports,\n Signature[] calldata _signatures\n ) external onlyRole(RELAYER_ROLE) {\n _relayGlobalProposal(\n _globalProposal,\n _supports,\n _signatures,\n DOMAIN_SEPARATOR,\n roninTrustedOrganizationContract(),\n bridgeContract(),\n msg.sender\n );\n }\n\n /**\n * @dev See `BOsGovernanceRelay-_relayVotesBySignatures`.\n *\n * Requirements:\n * - The method caller is relayer.\n *\n */\n function relayBridgeOperators(\n uint256 _period,\n address[] calldata _operators,\n Signature[] calldata _signatures\n ) external onlyRole(RELAYER_ROLE) {\n _relayVotesBySignatures(_operators, _signatures, _period, _getMinimumVoteWeight(), DOMAIN_SEPARATOR);\n TransparentUpgradeableProxyV2(payable(bridgeContract())).functionDelegateCall(\n abi.encodeWithSelector(_bridgeContract.replaceBridgeOperators.selector, _operators)\n );\n }\n\n /**\n * @inheritdoc GovernanceRelay\n */\n function _sumWeights(address[] memory _governors) internal view virtual override returns (uint256) {\n (bool _success, bytes memory _returndata) = roninTrustedOrganizationContract().staticcall(\n abi.encodeWithSelector(\n // TransparentUpgradeableProxyV2.functionDelegateCall.selector,\n 0x4bb5274a,\n abi.encodeWithSelector(IRoninTrustedOrganization.sumGovernorWeights.selector, _governors)\n )\n );\n require(_success, \"MainchainGovernanceAdmin: proxy call `sumGovernorWeights(address[])` failed\");\n return abi.decode(_returndata, (uint256));\n }\n\n /**\n * @inheritdoc BOsGovernanceRelay\n */\n function _sumBridgeVoterWeights(address[] memory _governors) internal view virtual override returns (uint256) {\n (bool _success, bytes memory _returndata) = roninTrustedOrganizationContract().staticcall(\n abi.encodeWithSelector(\n // TransparentUpgradeableProxyV2.functionDelegateCall.selector,\n 0x4bb5274a,\n abi.encodeWithSelector(IRoninTrustedOrganization.sumBridgeVoterWeights.selector, _governors)\n )\n );\n require(_success, \"MainchainGovernanceAdmin: proxy call `sumBridgeVoterWeights(address[])` failed\");\n return abi.decode(_returndata, (uint256));\n }\n\n /**\n * @dev See {CoreGovernance-_getChainType}\n */\n function _getChainType() internal pure override returns (ChainType) {\n return ChainType.Mainchain;\n }\n}\n" + }, + "contracts/extensions/sequential-governance/GovernanceRelay.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./CoreGovernance.sol\";\n\nabstract contract GovernanceRelay is CoreGovernance {\n using Proposal for Proposal.ProposalDetail;\n using GlobalProposal for GlobalProposal.GlobalProposalDetail;\n\n /**\n * @dev Relays votes by signatures.\n *\n * @notice Does not store the voter signature into storage.\n *\n */\n function _relayVotesBySignatures(\n Proposal.ProposalDetail memory _proposal,\n Ballot.VoteType[] calldata _supports,\n Signature[] calldata _signatures,\n bytes32 _forDigest,\n bytes32 _againstDigest\n ) internal {\n require(_supports.length > 0 && _supports.length == _signatures.length, \"GovernanceRelay: invalid array length\");\n uint256 _forVoteCount;\n uint256 _againstVoteCount;\n address[] memory _forVoteSigners = new address[](_signatures.length);\n address[] memory _againstVoteSigners = new address[](_signatures.length);\n\n {\n address _signer;\n address _lastSigner;\n Ballot.VoteType _support;\n Signature memory _sig;\n\n for (uint256 _i; _i < _signatures.length; _i++) {\n _sig = _signatures[_i];\n _support = _supports[_i];\n\n if (_support == Ballot.VoteType.For) {\n _signer = ECDSA.recover(_forDigest, _sig.v, _sig.r, _sig.s);\n _forVoteSigners[_forVoteCount++] = _signer;\n } else if (_support == Ballot.VoteType.Against) {\n _signer = ECDSA.recover(_againstDigest, _sig.v, _sig.r, _sig.s);\n _againstVoteSigners[_againstVoteCount++] = _signer;\n } else {\n revert(\"GovernanceRelay: query for unsupported vote type\");\n }\n\n require(_lastSigner < _signer, \"GovernanceRelay: invalid order\");\n _lastSigner = _signer;\n }\n }\n\n assembly {\n mstore(_forVoteSigners, _forVoteCount)\n mstore(_againstVoteSigners, _againstVoteCount)\n }\n\n ProposalVote storage _vote = vote[_proposal.chainId][_proposal.nonce];\n uint256 _minimumForVoteWeight = _getMinimumVoteWeight();\n uint256 _totalForVoteWeight = _sumWeights(_forVoteSigners);\n if (_totalForVoteWeight >= _minimumForVoteWeight) {\n require(_totalForVoteWeight > 0, \"GovernanceRelay: invalid vote weight\");\n _vote.status = VoteStatus.Approved;\n emit ProposalApproved(_vote.hash);\n _tryExecute(_vote, _proposal);\n return;\n }\n\n uint256 _minimumAgainstVoteWeight = _getTotalWeights() - _minimumForVoteWeight + 1;\n uint256 _totalAgainstVoteWeight = _sumWeights(_againstVoteSigners);\n if (_totalAgainstVoteWeight >= _minimumAgainstVoteWeight) {\n require(_totalAgainstVoteWeight > 0, \"GovernanceRelay: invalid vote weight\");\n _vote.status = VoteStatus.Rejected;\n emit ProposalRejected(_vote.hash);\n return;\n }\n\n revert(\"GovernanceRelay: relay failed\");\n }\n\n /**\n * @dev Relays voted proposal.\n *\n * Requirements:\n * - The relay proposal is finalized.\n *\n */\n function _relayProposal(\n Proposal.ProposalDetail calldata _proposal,\n Ballot.VoteType[] calldata _supports,\n Signature[] calldata _signatures,\n bytes32 _domainSeparator,\n address _creator\n ) internal {\n _proposeProposalStruct(_proposal, _creator);\n bytes32 _proposalHash = _proposal.hash();\n _relayVotesBySignatures(\n _proposal,\n _supports,\n _signatures,\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_proposalHash, Ballot.VoteType.For)),\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_proposalHash, Ballot.VoteType.Against))\n );\n }\n\n /**\n * @dev Relays voted global proposal.\n *\n * Requirements:\n * - The relay proposal is finalized.\n *\n */\n function _relayGlobalProposal(\n GlobalProposal.GlobalProposalDetail calldata _globalProposal,\n Ballot.VoteType[] calldata _supports,\n Signature[] calldata _signatures,\n bytes32 _domainSeparator,\n address _roninTrustedOrganizationContract,\n address _gatewayContract,\n address _creator\n ) internal {\n (Proposal.ProposalDetail memory _proposal, ) = _proposeGlobalStruct(\n _globalProposal,\n _roninTrustedOrganizationContract,\n _gatewayContract,\n _creator\n );\n bytes32 _globalProposalHash = _globalProposal.hash();\n _relayVotesBySignatures(\n _proposal,\n _supports,\n _signatures,\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_globalProposalHash, Ballot.VoteType.For)),\n ECDSA.toTypedDataHash(_domainSeparator, Ballot.hash(_globalProposalHash, Ballot.VoteType.Against))\n );\n }\n\n /**\n * @dev Returns the weight of the governor list.\n */\n function _sumWeights(address[] memory _governors) internal view virtual returns (uint256);\n}\n" + }, + "contracts/extensions/TransparentUpgradeableProxyV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol\";\n\ncontract TransparentUpgradeableProxyV2 is TransparentUpgradeableProxy {\n constructor(\n address _logic,\n address admin_,\n bytes memory _data\n ) payable TransparentUpgradeableProxy(_logic, admin_, _data) {}\n\n /**\n * @dev Calls a function from the current implementation as specified by `_data`, which should be an encoded function call.\n *\n * Requirements:\n * - Only the admin can call this function.\n *\n * Note: The proxy admin is not allowed to interact with the proxy logic through the fallback function to avoid\n * triggering some unexpected logic. This is to allow the administrator to explicitly call the proxy, please consider\n * reviewing the encoded data `_data` and the method which is called before using this.\n *\n */\n function functionDelegateCall(bytes memory _data) public payable ifAdmin {\n address _addr = _implementation();\n assembly {\n let _result := delegatecall(gas(), _addr, add(_data, 32), mload(_data), 0, 0)\n returndatacopy(0, 0, returndatasize())\n switch _result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n}\n" + }, + "contracts/mainchain/MainchainGatewayV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/access/AccessControlEnumerable.sol\";\nimport \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport \"../extensions/GatewayV2.sol\";\nimport \"../extensions/WithdrawalLimitation.sol\";\nimport \"../libraries/Transfer.sol\";\nimport \"../interfaces/IMainchainGatewayV2.sol\";\n\ncontract MainchainGatewayV2 is WithdrawalLimitation, Initializable, AccessControlEnumerable, IMainchainGatewayV2 {\n using Token for Token.Info;\n using Transfer for Transfer.Request;\n using Transfer for Transfer.Receipt;\n\n /// @dev Emitted when the bridge operators are replaced\n event BridgeOperatorsReplaced(address[] operators);\n\n /// @dev Withdrawal unlocker role hash\n bytes32 public constant WITHDRAWAL_UNLOCKER_ROLE = keccak256(\"WITHDRAWAL_UNLOCKER_ROLE\");\n\n /// @dev Wrapped native token address\n IWETH public wrappedNativeToken;\n /// @dev Ronin network id\n uint256 public roninChainId;\n /// @dev Total deposit\n uint256 public depositCount;\n /// @dev Domain seperator\n bytes32 internal _domainSeparator;\n /// @dev Mapping from mainchain token => token address on Ronin network\n mapping(address => MappedToken) internal _roninToken;\n /// @dev Mapping from withdrawal id => withdrawal hash\n mapping(uint256 => bytes32) public withdrawalHash;\n /// @dev Mapping from withdrawal id => locked\n mapping(uint256 => bool) public withdrawalLocked;\n\n /// @dev Mapping from validator address => last block that the bridge operator is added\n mapping(address => uint256) internal _bridgeOperatorAddedBlock;\n /// @dev Bridge operators array\n address[] internal _bridgeOperators;\n\n fallback() external payable {\n _fallback();\n }\n\n receive() external payable {\n _fallback();\n }\n\n /**\n * @dev Initializes contract storage.\n */\n function initialize(\n address _roleSetter,\n IWETH _wrappedToken,\n uint256 _roninChainId,\n uint256 _numerator,\n uint256 _highTierVWNumerator,\n uint256 _denominator,\n // _addresses[0]: mainchainTokens\n // _addresses[1]: roninTokens\n // _addresses[2]: withdrawalUnlockers\n address[][3] calldata _addresses,\n // _thresholds[0]: highTierThreshold\n // _thresholds[1]: lockedThreshold\n // _thresholds[2]: unlockFeePercentages\n // _thresholds[3]: dailyWithdrawalLimit\n uint256[][4] calldata _thresholds,\n Token.Standard[] calldata _standards\n ) external payable virtual initializer {\n _setupRole(DEFAULT_ADMIN_ROLE, _roleSetter);\n roninChainId = _roninChainId;\n\n _setWrappedNativeTokenContract(_wrappedToken);\n _updateDomainSeparator();\n _setThreshold(_numerator, _denominator);\n _setHighTierVoteWeightThreshold(_highTierVWNumerator, _denominator);\n _verifyThresholds();\n\n if (_addresses[0].length > 0) {\n // Map mainchain tokens to ronin tokens\n _mapTokens(_addresses[0], _addresses[1], _standards);\n // Sets thresholds based on the mainchain tokens\n _setHighTierThresholds(_addresses[0], _thresholds[0]);\n _setLockedThresholds(_addresses[0], _thresholds[1]);\n _setUnlockFeePercentages(_addresses[0], _thresholds[2]);\n _setDailyWithdrawalLimits(_addresses[0], _thresholds[3]);\n }\n\n // Grant role for withdrawal unlocker\n for (uint256 _i; _i < _addresses[2].length; _i++) {\n _grantRole(WITHDRAWAL_UNLOCKER_ROLE, _addresses[2][_i]);\n }\n }\n\n /**\n * @inheritdoc IBridge\n */\n function replaceBridgeOperators(address[] calldata _list) external onlyAdmin {\n address _addr;\n for (uint256 _i = 0; _i < _list.length; _i++) {\n _addr = _list[_i];\n if (_bridgeOperatorAddedBlock[_addr] == 0) {\n _bridgeOperators.push(_addr);\n }\n _bridgeOperatorAddedBlock[_addr] = block.number;\n }\n\n {\n uint256 _i;\n while (_i < _bridgeOperators.length) {\n _addr = _bridgeOperators[_i];\n if (_bridgeOperatorAddedBlock[_addr] < block.number) {\n delete _bridgeOperatorAddedBlock[_addr];\n _bridgeOperators[_i] = _bridgeOperators[_bridgeOperators.length - 1];\n _bridgeOperators.pop();\n continue;\n }\n _i++;\n }\n }\n\n emit BridgeOperatorsReplaced(_list);\n }\n\n /**\n * @inheritdoc IBridge\n */\n function getBridgeOperators() external view returns (address[] memory) {\n return _bridgeOperators;\n }\n\n /**\n * @dev Receives ether without doing anything. Use this function to topup native token.\n */\n function receiveEther() external payable {}\n\n /**\n * @inheritdoc IMainchainGatewayV2\n */\n function DOMAIN_SEPARATOR() external view virtual returns (bytes32) {\n return _domainSeparator;\n }\n\n /**\n * @inheritdoc IMainchainGatewayV2\n */\n function setWrappedNativeTokenContract(IWETH _wrappedToken) external virtual onlyAdmin {\n _setWrappedNativeTokenContract(_wrappedToken);\n }\n\n /**\n * @inheritdoc IMainchainGatewayV2\n */\n function requestDepositFor(Transfer.Request calldata _request) external payable virtual whenNotPaused {\n _requestDepositFor(_request, msg.sender);\n }\n\n /**\n * @inheritdoc IMainchainGatewayV2\n */\n function submitWithdrawal(Transfer.Receipt calldata _receipt, Signature[] calldata _signatures)\n external\n virtual\n whenNotPaused\n returns (bool _locked)\n {\n return _submitWithdrawal(_receipt, _signatures);\n }\n\n /**\n * @inheritdoc IMainchainGatewayV2\n */\n function unlockWithdrawal(Transfer.Receipt calldata _receipt) external onlyRole(WITHDRAWAL_UNLOCKER_ROLE) {\n bytes32 _receiptHash = _receipt.hash();\n require(withdrawalHash[_receipt.id] == _receipt.hash(), \"MainchainGatewayV2: invalid receipt\");\n require(withdrawalLocked[_receipt.id], \"MainchainGatewayV2: query for approved withdrawal\");\n delete withdrawalLocked[_receipt.id];\n emit WithdrawalUnlocked(_receiptHash, _receipt);\n\n address _token = _receipt.mainchain.tokenAddr;\n if (_receipt.info.erc == Token.Standard.ERC20) {\n Token.Info memory _feeInfo = _receipt.info;\n _feeInfo.quantity = _computeFeePercentage(_receipt.info.quantity, unlockFeePercentages[_token]);\n Token.Info memory _withdrawInfo = _receipt.info;\n _withdrawInfo.quantity = _receipt.info.quantity - _feeInfo.quantity;\n\n _feeInfo.handleAssetTransfer(payable(msg.sender), _token, wrappedNativeToken);\n _withdrawInfo.handleAssetTransfer(payable(_receipt.mainchain.addr), _token, wrappedNativeToken);\n } else {\n _receipt.info.handleAssetTransfer(payable(_receipt.mainchain.addr), _token, wrappedNativeToken);\n }\n\n emit Withdrew(_receiptHash, _receipt);\n }\n\n /**\n * @inheritdoc IMainchainGatewayV2\n */\n function mapTokens(\n address[] calldata _mainchainTokens,\n address[] calldata _roninTokens,\n Token.Standard[] calldata _standards\n ) external virtual onlyAdmin {\n require(_mainchainTokens.length > 0, \"MainchainGatewayV2: query for empty array\");\n _mapTokens(_mainchainTokens, _roninTokens, _standards);\n }\n\n /**\n * @inheritdoc IMainchainGatewayV2\n */\n function mapTokensAndThresholds(\n address[] calldata _mainchainTokens,\n address[] calldata _roninTokens,\n Token.Standard[] calldata _standards,\n // _thresholds[0]: highTierThreshold\n // _thresholds[1]: lockedThreshold\n // _thresholds[2]: unlockFeePercentages\n // _thresholds[3]: dailyWithdrawalLimit\n uint256[][4] calldata _thresholds\n ) external virtual onlyAdmin {\n require(_mainchainTokens.length > 0, \"MainchainGatewayV2: query for empty array\");\n _mapTokens(_mainchainTokens, _roninTokens, _standards);\n _setHighTierThresholds(_mainchainTokens, _thresholds[0]);\n _setLockedThresholds(_mainchainTokens, _thresholds[1]);\n _setUnlockFeePercentages(_mainchainTokens, _thresholds[2]);\n _setDailyWithdrawalLimits(_mainchainTokens, _thresholds[3]);\n }\n\n /**\n * @inheritdoc IMainchainGatewayV2\n */\n function getRoninToken(address _mainchainToken) public view returns (MappedToken memory _token) {\n _token = _roninToken[_mainchainToken];\n require(_token.tokenAddr != address(0), \"MainchainGatewayV2: unsupported token\");\n }\n\n /**\n * @dev Maps mainchain tokens to Ronin network.\n *\n * Requirement:\n * - The arrays have the same length.\n *\n * Emits the `TokenMapped` event.\n *\n */\n function _mapTokens(\n address[] calldata _mainchainTokens,\n address[] calldata _roninTokens,\n Token.Standard[] calldata _standards\n ) internal virtual {\n require(\n _mainchainTokens.length == _roninTokens.length && _mainchainTokens.length == _standards.length,\n \"MainchainGatewayV2: invalid array length\"\n );\n\n for (uint256 _i; _i < _mainchainTokens.length; _i++) {\n _roninToken[_mainchainTokens[_i]].tokenAddr = _roninTokens[_i];\n _roninToken[_mainchainTokens[_i]].erc = _standards[_i];\n }\n\n emit TokenMapped(_mainchainTokens, _roninTokens, _standards);\n }\n\n /**\n * @dev Submits withdrawal receipt.\n *\n * Requirements:\n * - The receipt kind is withdrawal.\n * - The receipt is to withdraw on this chain.\n * - The receipt is not used to withdraw before.\n * - The withdrawal is not reached the limit threshold.\n * - The signer weight total is larger than or equal to the minimum threshold.\n * - The signature signers are in order.\n *\n * Emits the `Withdrew` once the assets are released.\n *\n */\n function _submitWithdrawal(Transfer.Receipt calldata _receipt, Signature[] memory _signatures)\n internal\n virtual\n returns (bool _locked)\n {\n uint256 _id = _receipt.id;\n uint256 _quantity = _receipt.info.quantity;\n address _tokenAddr = _receipt.mainchain.tokenAddr;\n\n _receipt.info.validate();\n require(_receipt.kind == Transfer.Kind.Withdrawal, \"MainchainGatewayV2: invalid receipt kind\");\n require(_receipt.mainchain.chainId == block.chainid, \"MainchainGatewayV2: invalid chain id\");\n MappedToken memory _token = getRoninToken(_receipt.mainchain.tokenAddr);\n require(\n _token.erc == _receipt.info.erc && _token.tokenAddr == _receipt.ronin.tokenAddr,\n \"MainchainGatewayV2: invalid receipt\"\n );\n require(withdrawalHash[_id] == bytes32(0), \"MainchainGatewayV2: query for processed withdrawal\");\n require(\n _receipt.info.erc == Token.Standard.ERC721 || !_reachedWithdrawalLimit(_tokenAddr, _quantity),\n \"MainchainGatewayV2: reached daily withdrawal limit\"\n );\n\n bytes32 _receiptHash = _receipt.hash();\n bytes32 _receiptDigest = Transfer.receiptDigest(_domainSeparator, _receiptHash);\n\n uint256 _minimumVoteWeight;\n (_minimumVoteWeight, _locked) = _computeMinVoteWeight(_receipt.info.erc, _tokenAddr, _quantity);\n\n {\n bool _passed;\n address _signer;\n address _lastSigner;\n Signature memory _sig;\n uint256 _weight;\n for (uint256 _i; _i < _signatures.length; _i++) {\n _sig = _signatures[_i];\n _signer = ecrecover(_receiptDigest, _sig.v, _sig.r, _sig.s);\n require(_lastSigner < _signer, \"MainchainGatewayV2: invalid order\");\n _lastSigner = _signer;\n\n _weight += _getWeight(_signer);\n if (_weight >= _minimumVoteWeight) {\n _passed = true;\n break;\n }\n }\n require(_passed, \"MainchainGatewayV2: query for insufficient vote weight\");\n withdrawalHash[_id] = _receiptHash;\n }\n\n if (_locked) {\n withdrawalLocked[_id] = true;\n emit WithdrawalLocked(_receiptHash, _receipt);\n return _locked;\n }\n\n _recordWithdrawal(_tokenAddr, _quantity);\n _receipt.info.handleAssetTransfer(payable(_receipt.mainchain.addr), _tokenAddr, wrappedNativeToken);\n emit Withdrew(_receiptHash, _receipt);\n }\n\n /**\n * @dev Requests deposit made by `_requester` address.\n *\n * Requirements:\n * - The token info is valid.\n * - The `msg.value` is 0 while depositing ERC20 token.\n * - The `msg.value` is equal to deposit quantity while depositing native token.\n *\n * Emits the `DepositRequested` event.\n *\n */\n function _requestDepositFor(Transfer.Request memory _request, address _requester) internal virtual {\n MappedToken memory _token;\n address _weth = address(wrappedNativeToken);\n\n _request.info.validate();\n if (_request.tokenAddr == address(0)) {\n require(_request.info.quantity == msg.value, \"MainchainGatewayV2: invalid request\");\n _token = getRoninToken(_weth);\n require(_token.erc == _request.info.erc, \"MainchainGatewayV2: invalid token standard\");\n _request.tokenAddr = _weth;\n } else {\n require(msg.value == 0, \"MainchainGatewayV2: invalid request\");\n _token = getRoninToken(_request.tokenAddr);\n require(_token.erc == _request.info.erc, \"MainchainGatewayV2: invalid token standard\");\n _request.info.transferFrom(_requester, address(this), _request.tokenAddr);\n // Withdraw if token is WETH\n if (_weth == _request.tokenAddr) {\n IWETH(_weth).withdraw(_request.info.quantity);\n }\n }\n\n uint256 _depositId = depositCount++;\n Transfer.Receipt memory _receipt = _request.into_deposit_receipt(\n _requester,\n _depositId,\n _token.tokenAddr,\n roninChainId\n );\n\n emit DepositRequested(_receipt.hash(), _receipt);\n }\n\n /**\n * @dev Returns the minimum vote weight for the token.\n */\n function _computeMinVoteWeight(\n Token.Standard _erc,\n address _token,\n uint256 _quantity\n ) internal virtual returns (uint256 _weight, bool _locked) {\n uint256 _totalWeight = _getTotalWeight();\n _weight = _minimumVoteWeight(_totalWeight);\n if (_erc == Token.Standard.ERC20) {\n if (highTierThreshold[_token] <= _quantity) {\n _weight = _highTierVoteWeight(_totalWeight);\n }\n _locked = _lockedWithdrawalRequest(_token, _quantity);\n }\n }\n\n /**\n * @dev Update domain seperator.\n */\n function _updateDomainSeparator() internal {\n _domainSeparator = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(\"MainchainGatewayV2\"),\n keccak256(\"2\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /**\n * @dev Sets the WETH contract.\n *\n * Emits the `WrappedNativeTokenContractUpdated` event.\n *\n */\n function _setWrappedNativeTokenContract(IWETH _wrapedToken) internal {\n wrappedNativeToken = _wrapedToken;\n emit WrappedNativeTokenContractUpdated(_wrapedToken);\n }\n\n /**\n * @dev Receives ETH from WETH or creates deposit request.\n */\n function _fallback() internal virtual whenNotPaused {\n if (msg.sender != address(wrappedNativeToken)) {\n Transfer.Request memory _request;\n _request.recipientAddr = msg.sender;\n _request.info.quantity = msg.value;\n _requestDepositFor(_request, _request.recipientAddr);\n }\n }\n\n /**\n * @inheritdoc GatewayV2\n */\n function _getTotalWeight() internal view override returns (uint256) {\n return _bridgeOperators.length;\n }\n\n /**\n * @dev Returns the weight of an address.\n */\n function _getWeight(address _addr) internal view returns (uint256) {\n return _bridgeOperatorAddedBlock[_addr] > 0 ? 1 : 0;\n }\n}\n" + }, + "contracts/extensions/WithdrawalLimitation.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./GatewayV2.sol\";\n\nabstract contract WithdrawalLimitation is GatewayV2 {\n /// @dev Emitted when the high-tier vote weight threshold is updated\n event HighTierVoteWeightThresholdUpdated(\n uint256 indexed nonce,\n uint256 indexed numerator,\n uint256 indexed denominator,\n uint256 previousNumerator,\n uint256 previousDenominator\n );\n /// @dev Emitted when the thresholds for high-tier withdrawals that requires high-tier vote weights are updated\n event HighTierThresholdsUpdated(address[] tokens, uint256[] thresholds);\n /// @dev Emitted when the thresholds for locked withdrawals are updated\n event LockedThresholdsUpdated(address[] tokens, uint256[] thresholds);\n /// @dev Emitted when the fee percentages to unlock withdraw are updated\n event UnlockFeePercentagesUpdated(address[] tokens, uint256[] percentages);\n /// @dev Emitted when the daily limit thresholds are updated\n event DailyWithdrawalLimitsUpdated(address[] tokens, uint256[] limits);\n\n uint256 public constant _MAX_PERCENTAGE = 1_000_000;\n\n uint256 internal _highTierVWNum;\n uint256 internal _highTierVWDenom;\n\n /// @dev Mapping from mainchain token => the amount thresholds for high-tier withdrawals that requires high-tier vote weights\n mapping(address => uint256) public highTierThreshold;\n /// @dev Mapping from mainchain token => the amount thresholds to lock withdrawal\n mapping(address => uint256) public lockedThreshold;\n /// @dev Mapping from mainchain token => unlock fee percentages for unlocker\n /// @notice Values 0-1,000,000 map to 0%-100%\n mapping(address => uint256) public unlockFeePercentages;\n /// @dev Mapping from mainchain token => daily limit amount for withdrawal\n mapping(address => uint256) public dailyWithdrawalLimit;\n /// @dev Mapping from token address => today withdrawal amount\n mapping(address => uint256) public lastSyncedWithdrawal;\n /// @dev Mapping from token address => last date synced to record the `lastSyncedWithdrawal`\n mapping(address => uint256) public lastDateSynced;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n /**\n * @dev Override `GatewayV2-setThreshold`.\n *\n * Requirements:\n * - The high-tier vote weight threshold must equal to or larger than the normal threshold.\n *\n */\n function setThreshold(uint256 _numerator, uint256 _denominator)\n external\n virtual\n override\n onlyAdmin\n returns (uint256 _previousNum, uint256 _previousDenom)\n {\n (_previousNum, _previousDenom) = _setThreshold(_numerator, _denominator);\n _verifyThresholds();\n }\n\n /**\n * @dev Returns the high-tier vote weight threshold.\n */\n function getHighTierVoteWeightThreshold() external view virtual returns (uint256, uint256) {\n return (_highTierVWNum, _highTierVWDenom);\n }\n\n /**\n * @dev Checks whether the `_voteWeight` passes the high-tier vote weight threshold.\n */\n function checkHighTierVoteWeightThreshold(uint256 _voteWeight) external view virtual returns (bool) {\n return _voteWeight * _highTierVWDenom >= _highTierVWNum * _getTotalWeight();\n }\n\n /**\n * @dev Sets high-tier vote weight threshold and returns the old one.\n *\n * Requirements:\n * - The method caller is admin.\n * - The high-tier vote weight threshold must equal to or larger than the normal threshold.\n *\n * Emits the `HighTierVoteWeightThresholdUpdated` event.\n *\n */\n function setHighTierVoteWeightThreshold(uint256 _numerator, uint256 _denominator)\n external\n virtual\n onlyAdmin\n returns (uint256 _previousNum, uint256 _previousDenom)\n {\n (_previousNum, _previousDenom) = _setHighTierVoteWeightThreshold(_numerator, _denominator);\n _verifyThresholds();\n }\n\n /**\n * @dev Sets the thresholds for high-tier withdrawals that requires high-tier vote weights.\n *\n * Requirements:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `HighTierThresholdsUpdated` event.\n *\n */\n function setHighTierThresholds(address[] calldata _tokens, uint256[] calldata _thresholds)\n external\n virtual\n onlyAdmin\n {\n require(_tokens.length > 0, \"WithdrawalLimitation: invalid array length\");\n _setHighTierThresholds(_tokens, _thresholds);\n }\n\n /**\n * @dev Sets the amount thresholds to lock withdrawal.\n *\n * Requirements:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `LockedThresholdsUpdated` event.\n *\n */\n function setLockedThresholds(address[] calldata _tokens, uint256[] calldata _thresholds) external virtual onlyAdmin {\n require(_tokens.length > 0, \"WithdrawalLimitation: invalid array length\");\n _setLockedThresholds(_tokens, _thresholds);\n }\n\n /**\n * @dev Sets fee percentages to unlock withdrawal.\n *\n * Requirements:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `UnlockFeePercentagesUpdated` event.\n *\n */\n function setUnlockFeePercentages(address[] calldata _tokens, uint256[] calldata _percentages)\n external\n virtual\n onlyAdmin\n {\n require(_tokens.length > 0, \"WithdrawalLimitation: invalid array length\");\n _setUnlockFeePercentages(_tokens, _percentages);\n }\n\n /**\n * @dev Sets daily limit amounts for the withdrawals.\n *\n * Requirements:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `DailyWithdrawalLimitsUpdated` event.\n *\n */\n function setDailyWithdrawalLimits(address[] calldata _tokens, uint256[] calldata _limits) external virtual onlyAdmin {\n require(_tokens.length > 0, \"WithdrawalLimitation: invalid array length\");\n _setDailyWithdrawalLimits(_tokens, _limits);\n }\n\n /**\n * @dev Checks whether the withdrawal reaches the limitation.\n */\n function reachedWithdrawalLimit(address _token, uint256 _quantity) external view virtual returns (bool) {\n return _reachedWithdrawalLimit(_token, _quantity);\n }\n\n /**\n * @dev Sets high-tier vote weight threshold and returns the old one.\n *\n * Emits the `HighTierVoteWeightThresholdUpdated` event.\n *\n */\n function _setHighTierVoteWeightThreshold(uint256 _numerator, uint256 _denominator)\n internal\n returns (uint256 _previousNum, uint256 _previousDenom)\n {\n require(_numerator <= _denominator, \"WithdrawalLimitation: invalid threshold\");\n _previousNum = _highTierVWNum;\n _previousDenom = _highTierVWDenom;\n _highTierVWNum = _numerator;\n _highTierVWDenom = _denominator;\n emit HighTierVoteWeightThresholdUpdated(nonce++, _numerator, _denominator, _previousNum, _previousDenom);\n }\n\n /**\n * @dev Sets the thresholds for high-tier withdrawals that requires high-tier vote weights.\n *\n * Requirements:\n * - The array lengths are equal.\n *\n * Emits the `HighTierThresholdsUpdated` event.\n *\n */\n function _setHighTierThresholds(address[] calldata _tokens, uint256[] calldata _thresholds) internal virtual {\n require(_tokens.length == _thresholds.length, \"WithdrawalLimitation: invalid array length\");\n for (uint256 _i; _i < _tokens.length; _i++) {\n highTierThreshold[_tokens[_i]] = _thresholds[_i];\n }\n emit HighTierThresholdsUpdated(_tokens, _thresholds);\n }\n\n /**\n * @dev Sets the amount thresholds to lock withdrawal.\n *\n * Requirements:\n * - The array lengths are equal.\n *\n * Emits the `LockedThresholdsUpdated` event.\n *\n */\n function _setLockedThresholds(address[] calldata _tokens, uint256[] calldata _thresholds) internal virtual {\n require(_tokens.length == _thresholds.length, \"WithdrawalLimitation: invalid array length\");\n for (uint256 _i; _i < _tokens.length; _i++) {\n lockedThreshold[_tokens[_i]] = _thresholds[_i];\n }\n emit LockedThresholdsUpdated(_tokens, _thresholds);\n }\n\n /**\n * @dev Sets fee percentages to unlock withdrawal.\n *\n * Requirements:\n * - The array lengths are equal.\n * - The percentage is equal to or less than 100_000.\n *\n * Emits the `UnlockFeePercentagesUpdated` event.\n *\n */\n function _setUnlockFeePercentages(address[] calldata _tokens, uint256[] calldata _percentages) internal virtual {\n require(_tokens.length == _percentages.length, \"WithdrawalLimitation: invalid array length\");\n for (uint256 _i; _i < _tokens.length; _i++) {\n require(_percentages[_i] <= _MAX_PERCENTAGE, \"WithdrawalLimitation: invalid percentage\");\n unlockFeePercentages[_tokens[_i]] = _percentages[_i];\n }\n emit UnlockFeePercentagesUpdated(_tokens, _percentages);\n }\n\n /**\n * @dev Sets daily limit amounts for the withdrawals.\n *\n * Requirements:\n * - The array lengths are equal.\n *\n * Emits the `DailyWithdrawalLimitsUpdated` event.\n *\n */\n function _setDailyWithdrawalLimits(address[] calldata _tokens, uint256[] calldata _limits) internal virtual {\n require(_tokens.length == _limits.length, \"WithdrawalLimitation: invalid array length\");\n for (uint256 _i; _i < _tokens.length; _i++) {\n dailyWithdrawalLimit[_tokens[_i]] = _limits[_i];\n }\n emit DailyWithdrawalLimitsUpdated(_tokens, _limits);\n }\n\n /**\n * @dev Checks whether the withdrawal reaches the daily limitation.\n *\n * Requirements:\n * - The daily withdrawal threshold should not apply for locked withdrawals.\n *\n */\n function _reachedWithdrawalLimit(address _token, uint256 _quantity) internal view virtual returns (bool) {\n if (_lockedWithdrawalRequest(_token, _quantity)) {\n return false;\n }\n\n uint256 _currentDate = block.timestamp / 1 days;\n if (_currentDate > lastDateSynced[_token]) {\n return dailyWithdrawalLimit[_token] <= _quantity;\n } else {\n return dailyWithdrawalLimit[_token] <= lastSyncedWithdrawal[_token] + _quantity;\n }\n }\n\n /**\n * @dev Record withdrawal token.\n */\n function _recordWithdrawal(address _token, uint256 _quantity) internal virtual {\n uint256 _currentDate = block.timestamp / 1 days;\n if (_currentDate > lastDateSynced[_token]) {\n lastDateSynced[_token] = _currentDate;\n lastSyncedWithdrawal[_token] = _quantity;\n } else {\n lastSyncedWithdrawal[_token] += _quantity;\n }\n }\n\n /**\n * @dev Returns whether the withdrawal request is locked or not.\n */\n function _lockedWithdrawalRequest(address _token, uint256 _quantity) internal view virtual returns (bool) {\n return lockedThreshold[_token] <= _quantity;\n }\n\n /**\n * @dev Computes fee percentage.\n */\n function _computeFeePercentage(uint256 _amount, uint256 _percentage) internal view virtual returns (uint256) {\n return (_amount * _percentage) / _MAX_PERCENTAGE;\n }\n\n /**\n * @dev Returns high-tier vote weight.\n */\n function _highTierVoteWeight(uint256 _totalWeight) internal view virtual returns (uint256) {\n return (_highTierVWNum * _totalWeight + _highTierVWDenom - 1) / _highTierVWDenom;\n }\n\n /**\n * @dev Validates whether the high-tier vote weight threshold is larger than the normal threshold.\n */\n function _verifyThresholds() internal view {\n require(_num * _highTierVWDenom <= _highTierVWNum * _denom, \"WithdrawalLimitation: invalid thresholds\");\n }\n}\n" + }, + "contracts/interfaces/IMainchainGatewayV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./IBridge.sol\";\nimport \"./IWETH.sol\";\nimport \"./consumers/SignatureConsumer.sol\";\nimport \"./consumers/MappedTokenConsumer.sol\";\nimport \"../libraries/Transfer.sol\";\n\ninterface IMainchainGatewayV2 is SignatureConsumer, MappedTokenConsumer, IBridge {\n /// @dev Emitted when the deposit is requested\n event DepositRequested(bytes32 receiptHash, Transfer.Receipt receipt);\n /// @dev Emitted when the assets are withdrawn\n event Withdrew(bytes32 receiptHash, Transfer.Receipt receipt);\n /// @dev Emitted when the tokens are mapped\n event TokenMapped(address[] mainchainTokens, address[] roninTokens, Token.Standard[] standards);\n /// @dev Emitted when the wrapped native token contract is updated\n event WrappedNativeTokenContractUpdated(IWETH weth);\n /// @dev Emitted when the withdrawal is locked\n event WithdrawalLocked(bytes32 receiptHash, Transfer.Receipt receipt);\n /// @dev Emitted when the withdrawal is unlocked\n event WithdrawalUnlocked(bytes32 receiptHash, Transfer.Receipt receipt);\n\n /**\n * @dev Returns the domain seperator.\n */\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n\n /**\n * @dev Returns deposit count.\n */\n function depositCount() external view returns (uint256);\n\n /**\n * @dev Sets the wrapped native token contract.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the `WrappedNativeTokenContractUpdated` event.\n *\n */\n function setWrappedNativeTokenContract(IWETH _wrappedToken) external;\n\n /**\n * @dev Returns whether the withdrawal is locked.\n */\n function withdrawalLocked(uint256 withdrawalId) external view returns (bool);\n\n /**\n * @dev Returns the withdrawal hash.\n */\n function withdrawalHash(uint256 withdrawalId) external view returns (bytes32);\n\n /**\n * @dev Locks the assets and request deposit.\n */\n function requestDepositFor(Transfer.Request calldata _request) external payable;\n\n /**\n * @dev Withdraws based on the receipt and the validator signatures.\n * Returns whether the withdrawal is locked.\n *\n * Emits the `Withdrew` once the assets are released.\n *\n */\n function submitWithdrawal(Transfer.Receipt memory _receipt, Signature[] memory _signatures)\n external\n returns (bool _locked);\n\n /**\n * @dev Approves a specific withdrawal.\n *\n * Requirements:\n * - The method caller is a validator.\n *\n * Emits the `Withdrew` once the assets are released.\n *\n */\n function unlockWithdrawal(Transfer.Receipt calldata _receipt) external;\n\n /**\n * @dev Maps mainchain tokens to Ronin network.\n *\n * Requirement:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `TokenMapped` event.\n *\n */\n function mapTokens(\n address[] calldata _mainchainTokens,\n address[] calldata _roninTokens,\n Token.Standard[] calldata _standards\n ) external;\n\n /**\n * @dev Maps mainchain tokens to Ronin network and sets thresholds.\n *\n * Requirement:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `TokenMapped` event.\n *\n */\n function mapTokensAndThresholds(\n address[] calldata _mainchainTokens,\n address[] calldata _roninTokens,\n Token.Standard[] calldata _standards,\n uint256[][4] calldata _thresholds\n ) external;\n\n /**\n * @dev Returns token address on Ronin network.\n * Note: Reverts for unsupported token.\n */\n function getRoninToken(address _mainchainToken) external view returns (MappedToken memory _token);\n}\n" + }, + "contracts/ronin/slash-indicator/SlashUnavailability.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"./CreditScore.sol\";\nimport \"../../interfaces/slash-indicator/ISlashUnavailability.sol\";\nimport \"../../extensions/collections/HasValidatorContract.sol\";\n\nabstract contract SlashUnavailability is ISlashUnavailability, HasValidatorContract {\n /// @dev The last block that a validator is slashed for unavailability.\n uint256 public lastUnavailabilitySlashedBlock;\n /// @dev Mapping from validator address => period index => unavailability indicator.\n mapping(address => mapping(uint256 => uint256)) internal _unavailabilityIndicator;\n\n /// @dev The mining reward will be deprecated, if (s)he missed more than this threshold.\n uint256 internal _unavailabilityTier1Threshold;\n /**\n * @dev The mining reward will be deprecated, (s)he will be put in jailed, and will be deducted\n * self-staking if (s)he misses more than this threshold.\n */\n uint256 internal _unavailabilityTier2Threshold;\n /// @dev The amount of RON to deduct from self-staking of a block producer when (s)he is slashed tier-2.\n uint256 internal _slashAmountForUnavailabilityTier2Threshold;\n /// @dev The number of blocks to jail a block producer when (s)he is slashed tier-2.\n uint256 internal _jailDurationForUnavailabilityTier2Threshold;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n modifier oncePerBlock() {\n require(\n block.number > lastUnavailabilitySlashedBlock,\n \"SlashIndicator: cannot slash a validator twice or slash more than one validator in one block\"\n );\n lastUnavailabilitySlashedBlock = block.number;\n _;\n }\n\n /**\n * @inheritdoc ISlashUnavailability\n */\n function slashUnavailability(address _validatorAddr) external override oncePerBlock {\n require(msg.sender == block.coinbase, \"SlashUnavailability: method caller must be coinbase\");\n if (!_shouldSlash(_validatorAddr)) {\n return;\n }\n\n uint256 _period = _validatorContract.currentPeriod();\n uint256 _count = ++_unavailabilityIndicator[_validatorAddr][_period];\n\n if (_count == _unavailabilityTier2Threshold) {\n emit Slashed(_validatorAddr, SlashType.UNAVAILABILITY_TIER_2, _period);\n _validatorContract.execSlash(\n _validatorAddr,\n block.number + _jailDurationForUnavailabilityTier2Threshold,\n _slashAmountForUnavailabilityTier2Threshold\n );\n } else if (_count == _unavailabilityTier1Threshold) {\n emit Slashed(_validatorAddr, SlashType.UNAVAILABILITY_TIER_1, _period);\n _validatorContract.execSlash(_validatorAddr, 0, 0);\n }\n }\n\n /**\n * @inheritdoc ISlashUnavailability\n */\n function setUnavailabilitySlashingConfigs(\n uint256 _tier1Threshold,\n uint256 _tier2Threshold,\n uint256 _slashAmountForTier2Threshold,\n uint256 _jailDurationForTier2Threshold\n ) external override onlyAdmin {\n _setUnavailabilitySlashingConfigs(\n _tier1Threshold,\n _tier2Threshold,\n _slashAmountForTier2Threshold,\n _jailDurationForTier2Threshold\n );\n }\n\n /**\n * @inheritdoc ISlashUnavailability\n */\n function getUnavailabilitySlashingConfigs()\n external\n view\n override\n returns (\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n _unavailabilityTier1Threshold,\n _unavailabilityTier2Threshold,\n _slashAmountForUnavailabilityTier2Threshold,\n _jailDurationForUnavailabilityTier2Threshold\n );\n }\n\n /**\n * @inheritdoc ISlashUnavailability\n */\n function currentUnavailabilityIndicator(address _validator) external view override returns (uint256) {\n return getUnavailabilityIndicator(_validator, _validatorContract.currentPeriod());\n }\n\n /**\n * @inheritdoc ISlashUnavailability\n */\n function getUnavailabilityIndicator(address _validator, uint256 _period)\n public\n view\n virtual\n override\n returns (uint256)\n {\n return _unavailabilityIndicator[_validator][_period];\n }\n\n /**\n * @dev Sets the unavailability indicator of the `_validator` at `_period`.\n */\n function _setUnavailabilityIndicator(\n address _validator,\n uint256 _period,\n uint256 _indicator\n ) internal virtual {\n _unavailabilityIndicator[_validator][_period] = _indicator;\n }\n\n /**\n * @dev See `ISlashUnavailability-setUnavailabilitySlashingConfigs`.\n */\n function _setUnavailabilitySlashingConfigs(\n uint256 _tier1Threshold,\n uint256 _tier2Threshold,\n uint256 _slashAmountForTier2Threshold,\n uint256 _jailDurationForTier2Threshold\n ) internal {\n require(_unavailabilityTier1Threshold <= _unavailabilityTier2Threshold, \"SlashUnavailability: invalid threshold\");\n _unavailabilityTier1Threshold = _tier1Threshold;\n _unavailabilityTier2Threshold = _tier2Threshold;\n _slashAmountForUnavailabilityTier2Threshold = _slashAmountForTier2Threshold;\n _jailDurationForUnavailabilityTier2Threshold = _jailDurationForTier2Threshold;\n emit UnavailabilitySlashingConfigsUpdated(\n _tier1Threshold,\n _tier2Threshold,\n _slashAmountForTier2Threshold,\n _jailDurationForTier2Threshold\n );\n }\n\n /**\n * @dev Returns whether the account `_addr` should be slashed or not.\n */\n function _shouldSlash(address _addr) internal view virtual returns (bool);\n}\n" + }, + "contracts/ronin/slash-indicator/CreditScore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../interfaces/slash-indicator/ICreditScore.sol\";\nimport \"../../extensions/collections/HasMaintenanceContract.sol\";\nimport \"../../extensions/collections/HasValidatorContract.sol\";\nimport \"../../extensions/consumers/PercentageConsumer.sol\";\nimport \"../../libraries/Math.sol\";\n\nabstract contract CreditScore is ICreditScore, HasValidatorContract, HasMaintenanceContract, PercentageConsumer {\n /// @dev Mapping from validator address => period index => whether bailed out before\n mapping(address => mapping(uint256 => bool)) internal _checkBailedOutAtPeriod;\n /// @dev Mapping from validator address => credit score\n mapping(address => uint256) internal _creditScore;\n\n /// @dev The max gained number of credit score per period.\n uint256 internal _gainCreditScore;\n /// @dev The max number of credit score that a validator can hold.\n uint256 internal _maxCreditScore;\n /// @dev The number that will be multiplied with the remaining jailed time to get the cost of bailing out.\n uint256 internal _bailOutCostMultiplier;\n /// @dev The percentage of reward to be cut off from the validator in the rest of the period after bailed out.\n uint256 internal _cutOffPercentageAfterBailout;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n /**\n * @inheritdoc ICreditScore\n */\n function updateCreditScores(address[] calldata _validators, uint256 _period) external override onlyValidatorContract {\n uint256 _periodStartAtBlock = _validatorContract.currentPeriodStartAtBlock();\n\n bool[] memory _jaileds = _validatorContract.checkManyJailed(_validators);\n bool[] memory _maintaineds = _maintenanceContract.checkManyMaintainedInBlockRange(\n _validators,\n _periodStartAtBlock,\n block.number\n );\n uint256[] memory _updatedCreditScores = new uint256[](_validators.length);\n\n for (uint _i = 0; _i < _validators.length; _i++) {\n address _validator = _validators[_i];\n\n uint256 _indicator = getUnavailabilityIndicator(_validator, _period);\n bool _isJailedInPeriod = _jaileds[_i];\n bool _isMaintainingInPeriod = _maintaineds[_i];\n\n uint256 _actualGain = (_isJailedInPeriod || _isMaintainingInPeriod)\n ? 0\n : Math.subNonNegative(_gainCreditScore, _indicator);\n uint256 _scoreBeforeGain = _creditScore[_validator];\n uint256 _scoreAfterGain = Math.addWithUpperbound(_creditScore[_validator], _actualGain, _maxCreditScore);\n\n if (_scoreBeforeGain != _scoreAfterGain) {\n _creditScore[_validator] = _scoreAfterGain;\n }\n\n _updatedCreditScores[_i] = _creditScore[_validator];\n }\n\n emit CreditScoresUpdated(_validators, _updatedCreditScores);\n }\n\n /**\n * @inheritdoc ICreditScore\n */\n function bailOut(address _consensusAddr) external override {\n require(\n _validatorContract.isValidatorCandidate(_consensusAddr),\n \"SlashIndicator: consensus address must be a validator candidate\"\n );\n require(\n _validatorContract.isCandidateAdmin(_consensusAddr, msg.sender),\n \"SlashIndicator: method caller must be a candidate admin\"\n );\n\n (bool _isJailed, , uint256 _jailedEpochLeft) = _validatorContract.getJailedTimeLeft(_consensusAddr);\n require(_isJailed, \"SlashIndicator: caller must be jailed in the current period\");\n\n uint256 _period = _validatorContract.currentPeriod();\n require(!_checkBailedOutAtPeriod[_consensusAddr][_period], \"SlashIndicator: validator has bailed out previously\");\n\n uint256 _score = _creditScore[_consensusAddr];\n uint256 _cost = _jailedEpochLeft * _bailOutCostMultiplier;\n require(_score >= _cost, \"SlashIndicator: insufficient credit score to bail out\");\n\n _validatorContract.execBailOut(_consensusAddr, _period);\n\n _creditScore[_consensusAddr] -= _cost;\n _setUnavailabilityIndicator(_consensusAddr, _period, 0);\n _checkBailedOutAtPeriod[_consensusAddr][_period] = true;\n }\n\n /**\n * @inheritdoc ICreditScore\n */\n function setCreditScoreConfigs(\n uint256 _gainScore,\n uint256 _maxScore,\n uint256 _bailOutMultiplier,\n uint256 _cutOffPercentage\n ) external override onlyAdmin {\n _setCreditScoreConfigs(_gainScore, _maxScore, _bailOutMultiplier, _cutOffPercentage);\n }\n\n /**\n * @dev See `ISlashUnavailability`\n */\n function getUnavailabilityIndicator(address _validator, uint256 _period) public view virtual returns (uint256);\n\n /**\n * @inheritdoc ICreditScore\n */\n function getCreditScoreConfigs()\n external\n view\n override\n returns (\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (_gainCreditScore, _maxCreditScore, _bailOutCostMultiplier, _cutOffPercentageAfterBailout);\n }\n\n /**\n * @inheritdoc ICreditScore\n */\n function getCreditScore(address _validator) external view override returns (uint256) {\n return _creditScore[_validator];\n }\n\n /**\n * @inheritdoc ICreditScore\n */\n function getManyCreditScores(address[] calldata _validators)\n public\n view\n override\n returns (uint256[] memory _resultList)\n {\n _resultList = new uint256[](_validators.length);\n\n for (uint _i = 0; _i < _resultList.length; _i++) {\n _resultList[_i] = _creditScore[_validators[_i]];\n }\n }\n\n /**\n * @inheritdoc ICreditScore\n */\n function checkBailedOutAtPeriod(address _validator, uint256 _period) external view override returns (bool) {\n return _checkBailedOutAtPeriod[_validator][_period];\n }\n\n /**\n * @dev See `SlashUnavailability`.\n */\n function _setUnavailabilityIndicator(\n address _validator,\n uint256 _period,\n uint256 _indicator\n ) internal virtual;\n\n /**\n * @dev See `ICreditScore-setCreditScoreConfigs`.\n */\n function _setCreditScoreConfigs(\n uint256 _gainScore,\n uint256 _maxScore,\n uint256 _bailOutMultiplier,\n uint256 _cutOffPercentage\n ) internal {\n require(_gainScore <= _maxScore, \"CreditScore: invalid credit score config\");\n require(_cutOffPercentage <= _MAX_PERCENTAGE, \"CreditScore: invalid cut off percentage config\");\n\n _gainCreditScore = _gainScore;\n _maxCreditScore = _maxScore;\n _bailOutCostMultiplier = _bailOutMultiplier;\n _cutOffPercentageAfterBailout = _cutOffPercentage;\n emit CreditScoreConfigsUpdated(_gainScore, _maxScore, _bailOutMultiplier, _cutOffPercentage);\n }\n}\n" + }, + "contracts/ronin/slash-indicator/SlashBridgeOperator.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../extensions/consumers/PercentageConsumer.sol\";\nimport \"../../extensions/collections/HasProxyAdmin.sol\";\nimport \"../../interfaces/slash-indicator/ISlashBridgeOperator.sol\";\n\nabstract contract SlashBridgeOperator is ISlashBridgeOperator, HasProxyAdmin, PercentageConsumer {\n /**\n * @dev The bridge operators will be deprecated reward if (s)he missed more than the ratio.\n * Values 0-10,000 map to 0%-100%.\n */\n uint256 internal _missingVotesRatioTier1;\n /**\n * @dev The bridge operators will be deprecated all rewards including bridge reward and mining reward if (s)he missed\n * more than the ratio. Values 0-10,000 map to 0%-100%.\n */\n uint256 internal _missingVotesRatioTier2;\n /// @dev The number of blocks to jail the corresponding block producer when its bridge operator is slashed tier-2.\n uint256 internal _jailDurationForMissingVotesRatioTier2;\n /// @dev The threshold to skip slashing the bridge operator in case the total number of votes in the bridge is too small.\n uint256 internal _skipBridgeOperatorSlashingThreshold;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n /**\n * @inheritdoc ISlashBridgeOperator\n */\n function getBridgeOperatorSlashingConfigs()\n external\n view\n override\n returns (\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n _missingVotesRatioTier1,\n _missingVotesRatioTier2,\n _jailDurationForMissingVotesRatioTier2,\n _skipBridgeOperatorSlashingThreshold\n );\n }\n\n /**\n * @inheritdoc ISlashBridgeOperator\n */\n function setBridgeOperatorSlashingConfigs(\n uint256 _ratioTier1,\n uint256 _ratioTier2,\n uint256 _jailDurationTier2,\n uint256 _skipSlashingThreshold\n ) external override onlyAdmin {\n _setBridgeOperatorSlashingConfigs(_ratioTier1, _ratioTier2, _jailDurationTier2, _skipSlashingThreshold);\n }\n\n /**\n * @dev See `ISlashBridgeOperator-setBridgeOperatorSlashingConfigs`.\n */\n function _setBridgeOperatorSlashingConfigs(\n uint256 _ratioTier1,\n uint256 _ratioTier2,\n uint256 _jailDurationTier2,\n uint256 _skipSlashingThreshold\n ) internal {\n require(\n _ratioTier1 <= _ratioTier2 && _ratioTier1 <= _MAX_PERCENTAGE && _ratioTier2 <= _MAX_PERCENTAGE,\n \"SlashIndicator: invalid ratios\"\n );\n _missingVotesRatioTier1 = _ratioTier1;\n _missingVotesRatioTier2 = _ratioTier2;\n _jailDurationForMissingVotesRatioTier2 = _jailDurationTier2;\n _skipBridgeOperatorSlashingThreshold = _skipSlashingThreshold;\n emit BridgeOperatorSlashingConfigsUpdated(_ratioTier1, _ratioTier2, _jailDurationTier2, _skipSlashingThreshold);\n }\n}\n" + }, + "contracts/ronin/slash-indicator/SlashIndicator.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport \"../../interfaces/slash-indicator/ISlashIndicator.sol\";\nimport \"./SlashDoubleSign.sol\";\nimport \"./SlashBridgeVoting.sol\";\nimport \"./SlashBridgeOperator.sol\";\nimport \"./SlashUnavailability.sol\";\nimport \"./CreditScore.sol\";\n\ncontract SlashIndicator is\n ISlashIndicator,\n SlashDoubleSign,\n SlashBridgeVoting,\n SlashBridgeOperator,\n SlashUnavailability,\n CreditScore,\n Initializable\n{\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @dev Initializes the contract storage.\n */\n function initialize(\n address __validatorContract,\n address __maintenanceContract,\n address __roninTrustedOrganizationContract,\n address __roninGovernanceAdminContract,\n // _bridgeOperatorSlashingConfigs[0]: _missingVotesRatioTier1\n // _bridgeOperatorSlashingConfigs[1]: _missingVotesRatioTier2\n // _bridgeOperatorSlashingConfigs[2]: _jailDurationForMissingVotesRatioTier2\n // _bridgeOperatorSlashingConfigs[3]: _skipBridgeOperatorSlashingThreshold\n uint256[4] calldata _bridgeOperatorSlashingConfigs,\n // _bridgeVotingSlashingConfigs[0]: _bridgeVotingThreshold\n // _bridgeVotingSlashingConfigs[1]: _bridgeVotingSlashAmount\n uint256[2] calldata _bridgeVotingSlashingConfigs,\n // _doubleSignSlashingConfigs[0]: _slashDoubleSignAmount\n // _doubleSignSlashingConfigs[1]: _doubleSigningJailUntilBlock\n uint256[2] calldata _doubleSignSlashingConfigs,\n // _unavailabilitySlashingConfigs[0]: _unavailabilityTier1Threshold\n // _unavailabilitySlashingConfigs[1]: _unavailabilityTier2Threshold\n // _unavailabilitySlashingConfigs[2]: _slashAmountForUnavailabilityTier2Threshold\n // _unavailabilitySlashingConfigs[3]: _jailDurationForUnavailabilityTier2Threshold\n uint256[4] calldata _unavailabilitySlashingConfigs,\n // _creditScoreConfigs[0]: _gainCreditScore\n // _creditScoreConfigs[1]: _maxCreditScore\n // _creditScoreConfigs[2]: _bailOutCostMultiplier\n // _creditScoreConfigs[3]: _cutOffPercentageAfterBailout\n uint256[4] calldata _creditScoreConfigs\n ) external initializer {\n _setValidatorContract(__validatorContract);\n _setMaintenanceContract(__maintenanceContract);\n _setRoninTrustedOrganizationContract(__roninTrustedOrganizationContract);\n _setRoninGovernanceAdminContract(__roninGovernanceAdminContract);\n _setBridgeOperatorSlashingConfigs(\n _bridgeOperatorSlashingConfigs[0],\n _bridgeOperatorSlashingConfigs[1],\n _bridgeOperatorSlashingConfigs[2],\n _bridgeOperatorSlashingConfigs[3]\n );\n _setBridgeVotingSlashingConfigs(_bridgeVotingSlashingConfigs[0], _bridgeVotingSlashingConfigs[1]);\n _setDoubleSignSlashingConfigs(_doubleSignSlashingConfigs[0], _doubleSignSlashingConfigs[1]);\n _setUnavailabilitySlashingConfigs(\n _unavailabilitySlashingConfigs[0],\n _unavailabilitySlashingConfigs[1],\n _unavailabilitySlashingConfigs[2],\n _unavailabilitySlashingConfigs[3]\n );\n _setCreditScoreConfigs(\n _creditScoreConfigs[0],\n _creditScoreConfigs[1],\n _creditScoreConfigs[2],\n _creditScoreConfigs[3]\n );\n }\n\n /**\n * @dev Helper for CreditScore contract to reset the indicator of the validator after bailing out.\n */\n function _setUnavailabilityIndicator(\n address _validator,\n uint256 _period,\n uint256 _indicator\n ) internal override(CreditScore, SlashUnavailability) {\n SlashUnavailability._setUnavailabilityIndicator(_validator, _period, _indicator);\n }\n\n /**\n * @dev Helper for CreditScore contract to query indicator of the validator.\n */\n function getUnavailabilityIndicator(address _validator, uint256 _period)\n public\n view\n override(CreditScore, ISlashUnavailability, SlashUnavailability)\n returns (uint256)\n {\n return SlashUnavailability.getUnavailabilityIndicator(_validator, _period);\n }\n\n /**\n * @dev Sanity check the address to be slashed\n */\n function _shouldSlash(address _addr) internal view override(SlashDoubleSign, SlashUnavailability) returns (bool) {\n return\n (msg.sender != _addr) &&\n _validatorContract.isBlockProducer(_addr) &&\n !_maintenanceContract.checkMaintained(_addr, block.number);\n }\n}\n" + }, + "contracts/ronin/slash-indicator/SlashDoubleSign.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../interfaces/slash-indicator/ISlashDoubleSign.sol\";\nimport \"../../precompile-usages/PrecompileUsageValidateDoubleSign.sol\";\nimport \"../../extensions/collections/HasValidatorContract.sol\";\n\nabstract contract SlashDoubleSign is ISlashDoubleSign, HasValidatorContract, PrecompileUsageValidateDoubleSign {\n /// @dev The amount of RON to slash double sign.\n uint256 internal _slashDoubleSignAmount;\n /// @dev The block number that the punished validator will be jailed until, due to double signing.\n uint256 internal _doubleSigningJailUntilBlock;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n /**\n * @inheritdoc ISlashDoubleSign\n */\n function slashDoubleSign(\n address _consensuAddr,\n bytes calldata _header1,\n bytes calldata _header2\n ) external override {\n require(msg.sender == block.coinbase, \"SlashIndicator: method caller must be coinbase\");\n if (!_shouldSlash(_consensuAddr)) {\n return;\n }\n\n if (_pcValidateEvidence(_header1, _header2)) {\n uint256 _period = _validatorContract.currentPeriod();\n emit Slashed(_consensuAddr, SlashType.DOUBLE_SIGNING, _period);\n _validatorContract.execSlash(_consensuAddr, _doubleSigningJailUntilBlock, _slashDoubleSignAmount);\n }\n }\n\n /**\n * @inheritdoc ISlashDoubleSign\n */\n function getDoubleSignSlashingConfigs() external view override returns (uint256, uint256) {\n return (_slashDoubleSignAmount, _doubleSigningJailUntilBlock);\n }\n\n /**\n * @inheritdoc ISlashDoubleSign\n */\n function setDoubleSignSlashingConfigs(uint256 _slashAmount, uint256 _jailUntilBlock) external override onlyAdmin {\n _setDoubleSignSlashingConfigs(_slashAmount, _jailUntilBlock);\n }\n\n /**\n * @dev See `ISlashDoubleSign-setDoubleSignSlashingConfigs`.\n */\n function _setDoubleSignSlashingConfigs(uint256 _slashAmount, uint256 _jailUntilBlock) internal {\n _slashDoubleSignAmount = _slashAmount;\n _doubleSigningJailUntilBlock = _jailUntilBlock;\n emit DoubleSignSlashingConfigsUpdated(_slashAmount, _jailUntilBlock);\n }\n\n /**\n * @dev Returns whether the account `_addr` should be slashed or not.\n */\n function _shouldSlash(address _addr) internal view virtual returns (bool);\n}\n" + }, + "contracts/precompile-usages/PrecompileUsageValidateDoubleSign.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nabstract contract PrecompileUsageValidateDoubleSign {\n /// @dev Gets the address of the precompile of validating double sign evidence\n function precompileValidateDoubleSignAddress() public view virtual returns (address) {\n return address(0x67);\n }\n\n /**\n * @dev Validates the two submitted block header if they are produced by the same address\n *\n * Note: The recover process is done by pre-compiled contract. This function is marked as\n * virtual for implementing mocking contract for testing purpose.\n */\n function _pcValidateEvidence(bytes calldata _header1, bytes calldata _header2)\n internal\n view\n virtual\n returns (bool _validEvidence)\n {\n address _smc = precompileValidateDoubleSignAddress();\n bool _success = true;\n\n bytes memory _payload = abi.encodeWithSignature(\"validatingDoubleSignProof(bytes,bytes)\", _header1, _header2);\n uint _payloadLength = _payload.length;\n uint[1] memory _output;\n\n assembly {\n let _payloadStart := add(_payload, 0x20)\n if iszero(staticcall(gas(), _smc, _payloadStart, _payloadLength, _output, 0x20)) {\n _success := 0\n }\n\n if iszero(returndatasize()) {\n _success := 0\n }\n }\n\n require(_success, \"PrecompileUsageValidateDoubleSign: call to precompile fails\");\n return (_output[0] != 0);\n }\n}\n" + }, + "contracts/mocks/precompile-usages/MockPrecompileUsageValidateDoubleSign.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../precompile-usages/PrecompileUsageValidateDoubleSign.sol\";\n\ncontract MockPrecompileUsageValidateDoubleSign is PrecompileUsageValidateDoubleSign {\n address internal _precompileValidateDoubleSignAddress;\n\n constructor(address _precompile) {\n setPrecompileValidateDoubleSignAddress(_precompile);\n }\n\n function setPrecompileValidateDoubleSignAddress(address _addr) public {\n _precompileValidateDoubleSignAddress = _addr;\n }\n\n function precompileValidateDoubleSignAddress() public view override returns (address) {\n return _precompileValidateDoubleSignAddress;\n }\n\n function callPrecompile(bytes calldata _header1, bytes calldata _header2) public view returns (bool) {\n return _pcValidateEvidence(_header1, _header2);\n }\n}\n" + }, + "contracts/mocks/MockSlashIndicatorExtended.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"./MockPrecompile.sol\";\nimport \"../ronin/slash-indicator/SlashIndicator.sol\";\n\ncontract MockSlashIndicatorExtended is SlashIndicator, MockPrecompile {\n function slashFelony(address _validatorAddr) external {\n _validatorContract.execSlash(_validatorAddr, 0, 0);\n }\n\n function slashMisdemeanor(address _validatorAddr) external {\n _validatorContract.execSlash(_validatorAddr, 0, 0);\n }\n\n function _pcValidateEvidence(bytes calldata _header1, bytes calldata _header2)\n internal\n pure\n override\n returns (bool _validEvidence)\n {\n return validatingDoubleSignProof(_header1, _header2);\n }\n}\n" + }, + "contracts/mocks/MockPrecompile.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"./libraries/Sorting.sol\";\nimport \"../libraries/Math.sol\";\n\ncontract MockPrecompile {\n function sortValidators(address[] memory _validators, uint256[] memory _weights)\n public\n pure\n returns (address[] memory)\n {\n return Sorting.sort(_validators, _weights);\n }\n\n function validatingDoubleSignProof(\n bytes calldata, /*_header1*/\n bytes calldata /*_header2*/\n ) public pure returns (bool _validEvidence) {\n return true;\n }\n\n function pickValidatorSet(\n address[] memory _candidates,\n uint256[] memory _weights,\n uint256[] memory _trustedWeights,\n uint256 _maxValidatorNumber,\n uint256 _maxPrioritizedValidatorNumber\n ) public pure returns (address[] memory _result) {\n (_result, _trustedWeights) = Sorting.sortWithExternalKeys(_candidates, _weights, _trustedWeights);\n uint256 _newValidatorCount = Math.min(_maxValidatorNumber, _result.length);\n _arrangeValidatorCandidates(_result, _trustedWeights, _newValidatorCount, _maxPrioritizedValidatorNumber);\n }\n\n /**\n * @dev Arranges the sorted candidates to list of validators, by asserting prioritized and non-prioritized candidates\n *\n * @param _candidates A sorted list of candidates\n */\n function _arrangeValidatorCandidates(\n address[] memory _candidates,\n uint256[] memory _trustedWeights,\n uint _newValidatorCount,\n uint _maxPrioritizedValidatorNumber\n ) internal pure {\n address[] memory _waitingCandidates = new address[](_candidates.length);\n uint _waitingCounter;\n uint _prioritySlotCounter;\n\n for (uint _i = 0; _i < _candidates.length; _i++) {\n if (_trustedWeights[_i] > 0 && _prioritySlotCounter < _maxPrioritizedValidatorNumber) {\n _candidates[_prioritySlotCounter++] = _candidates[_i];\n continue;\n }\n _waitingCandidates[_waitingCounter++] = _candidates[_i];\n }\n\n _waitingCounter = 0;\n for (uint _i = _prioritySlotCounter; _i < _newValidatorCount; _i++) {\n _candidates[_i] = _waitingCandidates[_waitingCounter++];\n }\n\n assembly {\n mstore(_candidates, _newValidatorCount)\n }\n }\n}\n" + }, + "contracts/mocks/libraries/Sorting.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\n\npragma solidity ^0.8.0;\n\nlibrary Sorting {\n struct Node {\n uint key;\n uint value;\n }\n\n struct Node3 {\n uint key;\n uint value;\n uint otherKey;\n }\n\n ///////////////////////////////////////////////////////////////////////////////////////\n // VALUE SORTING //\n ///////////////////////////////////////////////////////////////////////////////////////\n\n function sort(uint[] memory data) internal pure returns (uint[] memory) {\n return _quickSort(data, int(0), int(data.length - 1));\n }\n\n function _quickSort(\n uint[] memory arr,\n int left,\n int right\n ) private pure returns (uint[] memory) {\n int i = left;\n int j = right;\n if (i == j) return arr;\n uint pivot = arr[uint(left + (right - left) / 2)];\n while (i <= j) {\n while (arr[uint(i)] > pivot) i++;\n while (pivot > arr[uint(j)]) j--;\n if (i <= j) {\n (arr[uint(i)], arr[uint(j)]) = (arr[uint(j)], arr[uint(i)]);\n i++;\n j--;\n }\n }\n if (left < j) arr = _quickSort(arr, left, j);\n if (i < right) arr = _quickSort(arr, i, right);\n\n return arr;\n }\n\n ///////////////////////////////////////////////////////////////////////////////////////\n // NODE SORTING //\n ///////////////////////////////////////////////////////////////////////////////////////\n\n function sort(address[] memory _keys, uint256[] memory _values) internal pure returns (address[] memory) {\n require(_values.length == _keys.length, \"Sorting: invalid array length\");\n if (_keys.length == 0) {\n return _keys;\n }\n\n Node[] memory _nodes = new Node[](_keys.length);\n for (uint256 _i; _i < _nodes.length; _i++) {\n _nodes[_i] = Node(uint256(uint160(_keys[_i])), _values[_i]);\n }\n _quickSortNodes(_nodes, int(0), int(_nodes.length - 1));\n\n for (uint256 _i; _i < _nodes.length; _i++) {\n _keys[_i] = address(uint160(_nodes[_i].key)); // Casting?\n }\n\n return _keys;\n }\n\n function sortNodes(Node[] memory nodes) internal pure returns (Node[] memory) {\n return _quickSortNodes(nodes, int(0), int(nodes.length - 1));\n }\n\n function _quickSortNodes(\n Node[] memory nodes,\n int left,\n int right\n ) private pure returns (Node[] memory) {\n int i = left;\n int j = right;\n if (i == j) return nodes;\n Node memory pivot = nodes[uint(left + (right - left) / 2)];\n while (i <= j) {\n while (nodes[uint(i)].value > pivot.value) i++;\n while (pivot.value > nodes[uint(j)].value) j--;\n if (i <= j) {\n (nodes[uint(i)], nodes[uint(j)]) = __swapNodes(nodes[uint(i)], nodes[uint(j)]);\n i++;\n j--;\n }\n }\n if (left < j) nodes = _quickSortNodes(nodes, left, j);\n if (i < right) nodes = _quickSortNodes(nodes, i, right);\n\n return nodes;\n }\n\n function _bubbleSortNodes(Node[] memory nodes) private pure returns (Node[] memory) {\n uint length = nodes.length;\n for (uint i = 0; i < length - 1; i++) {\n for (uint j = i + 1; j < length; j++) {\n if (nodes[j].value > nodes[i].value) {\n (nodes[i], nodes[j]) = __swapNodes(nodes[i], nodes[j]);\n }\n }\n }\n return nodes;\n }\n\n function __swapNodes(Node memory x, Node memory y) private pure returns (Node memory, Node memory) {\n Node memory tmp = x;\n (x, y) = (y, tmp);\n return (x, y);\n }\n\n ///////////////////////////////////////////////////////////////////////////////////////\n // NODE3 SORTING //\n ///////////////////////////////////////////////////////////////////////////////////////\n\n function sortWithExternalKeys(\n address[] memory _keys,\n uint256[] memory _values,\n uint256[] memory _otherKeys\n ) internal pure returns (address[] memory keys_, uint256[] memory otherKeys_) {\n require((_values.length == _keys.length) && (_otherKeys.length == _keys.length), \"Sorting: invalid array length\");\n if (_keys.length == 0) {\n return (_keys, _otherKeys);\n }\n\n Node3[] memory _nodes = new Node3[](_keys.length);\n for (uint256 _i; _i < _nodes.length; _i++) {\n _nodes[_i] = Node3(uint256(uint160(_keys[_i])), _values[_i], _otherKeys[_i]);\n }\n _quickSortNode3s(_nodes, int(0), int(_nodes.length - 1));\n\n for (uint256 _i; _i < _nodes.length; _i++) {\n _keys[_i] = address(uint160(_nodes[_i].key)); // Casting?\n }\n\n return (_keys, _otherKeys);\n }\n\n function sortNode3s(Node3[] memory nodes) internal pure returns (Node3[] memory) {\n return _quickSortNode3s(nodes, int(0), int(nodes.length - 1));\n }\n\n function _quickSortNode3s(\n Node3[] memory nodes,\n int left,\n int right\n ) private pure returns (Node3[] memory) {\n int i = left;\n int j = right;\n if (i == j) return nodes;\n Node3 memory pivot = nodes[uint(left + (right - left) / 2)];\n while (i <= j) {\n while (nodes[uint(i)].value > pivot.value) i++;\n while (pivot.value > nodes[uint(j)].value) j--;\n if (i <= j) {\n (nodes[uint(i)], nodes[uint(j)]) = __swapNode3s(nodes[uint(i)], nodes[uint(j)]);\n i++;\n j--;\n }\n }\n if (left < j) nodes = _quickSortNode3s(nodes, left, j);\n if (i < right) nodes = _quickSortNode3s(nodes, i, right);\n\n return nodes;\n }\n\n function _bubbleSortNode3s(Node3[] memory nodes) private pure returns (Node3[] memory) {\n uint length = nodes.length;\n for (uint i = 0; i < length - 1; i++) {\n for (uint j = i + 1; j < length; j++) {\n if (nodes[j].value > nodes[i].value) {\n (nodes[i], nodes[j]) = __swapNode3s(nodes[i], nodes[j]);\n }\n }\n }\n return nodes;\n }\n\n function __swapNode3s(Node3 memory x, Node3 memory y) private pure returns (Node3 memory, Node3 memory) {\n Node3 memory tmp = x;\n (x, y) = (y, tmp);\n return (x, y);\n }\n}\n" + }, + "contracts/mocks/validator/MockRoninValidatorSetOverridePrecompile.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../MockPrecompile.sol\";\nimport \"../../ronin/validator/RoninValidatorSet.sol\";\n\ncontract MockRoninValidatorSetOverridePrecompile is RoninValidatorSet, MockPrecompile {\n constructor() {}\n\n function arrangeValidatorCandidates(\n address[] memory _candidates,\n uint256[] memory _trustedWeights,\n uint _newValidatorCount,\n uint _maxPrioritizedValidatorNumber\n ) external pure returns (address[] memory) {\n _arrangeValidatorCandidates(_candidates, _trustedWeights, _newValidatorCount, _maxPrioritizedValidatorNumber);\n return _candidates;\n }\n\n function _pcSortCandidates(address[] memory _candidates, uint256[] memory _weights)\n internal\n pure\n override\n returns (address[] memory _result)\n {\n return sortValidators(_candidates, _weights);\n }\n\n function _pcPickValidatorSet(\n address[] memory _candidates,\n uint256[] memory _weights,\n uint256[] memory _trustedWeights,\n uint256 _maxValidatorNumber,\n uint256 _maxPrioritizedValidatorNumber\n ) internal pure override returns (address[] memory _result, uint256 _newValidatorCount) {\n _result = pickValidatorSet(\n _candidates,\n _weights,\n _trustedWeights,\n _maxValidatorNumber,\n _maxPrioritizedValidatorNumber\n );\n\n _newValidatorCount = _result.length;\n }\n}\n" + }, + "contracts/mocks/validator/MockRoninValidatorSetExtended.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"./MockRoninValidatorSetOverridePrecompile.sol\";\nimport \"../../libraries/EnumFlags.sol\";\n\ncontract MockRoninValidatorSetExtended is MockRoninValidatorSetOverridePrecompile {\n uint256[] internal _epochs;\n\n constructor() {}\n\n function endEpoch() external {\n _epochs.push(block.number);\n }\n\n function epochOf(uint256 _block) public view override returns (uint256 _epoch) {\n for (uint256 _i = _epochs.length; _i > 0; _i--) {\n if (_block >= _epochs[_i - 1]) {\n return _i;\n }\n }\n }\n\n function epochEndingAt(uint256 _block) public view override(ITimingInfo, TimingStorage) returns (bool) {\n for (uint _i = 0; _i < _epochs.length; _i++) {\n if (_block == _epochs[_i]) {\n return true;\n }\n }\n return false;\n }\n\n function getJailUntils(address[] calldata _addrs) public view returns (uint256[] memory jailUntils_) {\n jailUntils_ = new uint256[](_addrs.length);\n for (uint _i = 0; _i < _addrs.length; _i++) {\n jailUntils_[_i] = _jailedUntil[_addrs[_i]];\n }\n }\n\n function addValidators(address[] calldata _addrs) public {\n for (uint _i = 0; _i < _addrs.length; _i++) {\n _validators[_i] = _addrs[_i];\n _validatorMap[_addrs[_i]] = EnumFlags.ValidatorFlag.Both;\n }\n }\n}\n" + }, + "contracts/mocks/sorting/MockSorting.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol\";\nimport \"../libraries/Sorting.sol\";\n\ncontract MockSorting {\n uint256[] public data;\n\n function addData(uint256[] memory _data) public {\n for (uint256 i; i < _data.length; i++) {\n data.push(_data[i]);\n }\n }\n\n function sort(uint256[] memory _data) public pure returns (uint256[] memory) {\n return Sorting.sort(_data);\n }\n\n function sortOnStorage() public returns (uint256[] memory, uint256) {\n uint256[] memory _tmpData = data;\n data = Sorting.sort(_tmpData);\n\n return (data, data.length);\n }\n\n function sortAddressesAndValues(address[] calldata _addrs, uint256[] calldata _values)\n public\n pure\n returns (address[] memory)\n {\n return Sorting.sort(_addrs, _values);\n }\n}\n" + }, + "contracts/mocks/MockStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../ronin/staking/RewardCalculation.sol\";\n\ncontract MockStaking is RewardCalculation {\n /// @dev Mapping from user => staking balance\n mapping(address => uint256) internal _stakingAmount;\n /// @dev Mapping from period number => slashed\n mapping(uint256 => bool) internal _periodSlashed;\n\n uint256 internal _stakingTotal;\n\n uint256 public lastUpdatedPeriod;\n uint256 public pendingReward;\n address public poolAddr;\n\n constructor(address _poolAddr) {\n poolAddr = _poolAddr;\n }\n\n function firstEverWrapup() external {\n delete pendingReward;\n lastUpdatedPeriod = block.timestamp / 1 days + 1;\n }\n\n function endPeriod() external {\n address[] memory _addrs = new address[](1);\n uint256[] memory _rewards = new uint256[](1);\n _addrs[0] = poolAddr;\n _rewards[0] = pendingReward;\n this.recordRewards(_addrs, _rewards);\n\n pendingReward = 0;\n lastUpdatedPeriod++;\n }\n\n function increasePeriod() external {\n lastUpdatedPeriod++;\n }\n\n function stake(address _user, uint256 _amount) external {\n uint256 _lastStakingAmount = _stakingAmount[_user];\n uint256 _newStakingAmount = _lastStakingAmount + _amount;\n _syncUserReward(poolAddr, _user, _newStakingAmount);\n _stakingAmount[_user] = _newStakingAmount;\n _stakingTotal += _amount;\n }\n\n function unstake(address _user, uint256 _amount) external {\n uint256 _lastStakingAmount = _stakingAmount[_user];\n uint256 _newStakingAmount = _lastStakingAmount - _amount;\n _syncUserReward(poolAddr, _user, _newStakingAmount);\n _stakingAmount[_user] = _newStakingAmount;\n _stakingTotal -= _amount;\n }\n\n function increaseReward(uint256 _amount) external {\n pendingReward += _amount;\n }\n\n function decreaseReward(uint256 _amount) external {\n pendingReward -= _amount;\n }\n\n function recordRewards(address[] calldata _addrList, uint256[] calldata _rewards) external {\n _recordRewards(_addrList, _rewards, _currentPeriod());\n }\n\n function getPeriod() public view returns (uint256) {\n return _currentPeriod();\n }\n\n function claimReward(address _user) external returns (uint256 _amount) {\n _amount = _claimReward(poolAddr, _user);\n }\n\n function getStakingAmount(address, address _user) public view override returns (uint256) {\n return _stakingAmount[_user];\n }\n\n function getManyStakingAmounts(address[] calldata _poolAddrs, address[] calldata _userList)\n external\n view\n override\n returns (uint256[] memory)\n {}\n\n function getStakingTotal(address _addr) public view virtual override returns (uint256) {\n return _addr == poolAddr ? _stakingTotal : 0;\n }\n\n function _currentPeriod() internal view override returns (uint256 _period) {\n return lastUpdatedPeriod;\n }\n\n function getManyStakingTotals(address[] calldata _poolAddr) external view override returns (uint256[] memory) {}\n}\n" + }, + "contracts/mocks/precompile-usages/MockPrecompileUsagePickValidatorSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../precompile-usages/PrecompileUsagePickValidatorSet.sol\";\n\ncontract MockPrecompileUsagePickValidatorSet is PrecompileUsagePickValidatorSet {\n address internal _precompileSortValidatorAddress;\n\n constructor(address _precompile) {\n setPrecompileSortValidatorAddress(_precompile);\n }\n\n function setPrecompileSortValidatorAddress(address _addr) public {\n _precompileSortValidatorAddress = _addr;\n }\n\n function precompilePickValidatorSetAddress() public view override returns (address) {\n return _precompileSortValidatorAddress;\n }\n\n function callPrecompile(\n address[] memory _candidates,\n uint256[] memory _weights,\n uint256[] memory _trustedWeights,\n uint256 _maxValidatorNumber,\n uint256 _maxPrioritizedValidatorNumber\n ) public view returns (address[] memory _result) {\n (_result, ) = _pcPickValidatorSet(\n _candidates,\n _weights,\n _trustedWeights,\n _maxValidatorNumber,\n _maxPrioritizedValidatorNumber\n );\n }\n}\n" + }, + "contracts/mocks/precompile-usages/MockPrecompileUsageSortValidators.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.9;\n\nimport \"../../precompile-usages/PrecompileUsageSortValidators.sol\";\n\ncontract MockPrecompileUsageSortValidators is PrecompileUsageSortValidators {\n address internal _precompileSortValidatorAddress;\n\n constructor(address _precompile) {\n setPrecompileSortValidatorAddress(_precompile);\n }\n\n function setPrecompileSortValidatorAddress(address _addr) public {\n _precompileSortValidatorAddress = _addr;\n }\n\n function precompileSortValidatorsAddress() public view override returns (address) {\n return _precompileSortValidatorAddress;\n }\n\n function callPrecompile(address[] calldata _validators, uint256[] calldata _weights)\n public\n view\n returns (address[] memory _result)\n {\n return _pcSortCandidates(_validators, _weights);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file