From 947ee6baaa8e641526c2d1ed588a92398901efb8 Mon Sep 17 00:00:00 2001 From: gathonwar Date: Wed, 20 Sep 2023 20:20:22 +0300 Subject: [PATCH] fix: add deploy scripts and deployments --- .../interfaces/ISonneMerkleDistributor.sol | 233 +------ .../00-sonne-merkle-distributor.base.ts | 22 + .../01-usdc-merkle-distributor.base copy.ts | 22 + .../deploy/02-aero-merkle-distributor.base.ts | 22 + crosschain-rewards/deployments/base/.chainId | 1 + .../base/SonneMerkleDistributor.json | 643 ++++++++++++++++++ .../base/UsdcMerkleDistributor.json | 643 ++++++++++++++++++ .../30087f7fee47449a419e52a71b53a636.json | 95 +++ crosschain-rewards/hardhat.config.ts | 69 +- crosschain-rewards/package-lock.json | 256 ++++++- crosschain-rewards/package.json | 1 + crosschain-rewards/scripts/getAccountRoot.ts | 20 +- crosschain-rewards/scripts/getProofForUser.ts | 22 +- .../contracts/token/ERC20/ERC20__factory.ts | 2 +- .../Delegator.sol/Delegate__factory.ts | 2 +- .../SonneMerkleDistributor__factory.ts | 2 +- .../contracts/TestContract__factory.ts | 2 +- .../contracts/mocks/ERC20Mock__factory.ts | 2 +- .../mocks/ERC20WithPermitMock__factory.ts | 2 +- 19 files changed, 1803 insertions(+), 258 deletions(-) create mode 100644 crosschain-rewards/deploy/00-sonne-merkle-distributor.base.ts create mode 100644 crosschain-rewards/deploy/01-usdc-merkle-distributor.base copy.ts create mode 100644 crosschain-rewards/deploy/02-aero-merkle-distributor.base.ts create mode 100644 crosschain-rewards/deployments/base/.chainId create mode 100644 crosschain-rewards/deployments/base/SonneMerkleDistributor.json create mode 100644 crosschain-rewards/deployments/base/UsdcMerkleDistributor.json create mode 100644 crosschain-rewards/deployments/base/solcInputs/30087f7fee47449a419e52a71b53a636.json diff --git a/crosschain-rewards/contracts/interfaces/ISonneMerkleDistributor.sol b/crosschain-rewards/contracts/interfaces/ISonneMerkleDistributor.sol index b73067e..4e08710 100644 --- a/crosschain-rewards/contracts/interfaces/ISonneMerkleDistributor.sol +++ b/crosschain-rewards/contracts/interfaces/ISonneMerkleDistributor.sol @@ -1,224 +1,47 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.19; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; -import {SecureMerkleTrie} from "@eth-optimism/contracts-bedrock/contracts/libraries/trie/SecureMerkleTrie.sol"; -import {RLPReader} from "@eth-optimism/contracts-bedrock/contracts/libraries/rlp/RLPReader.sol"; -import {ISonneMerkleDistributor} from "./interfaces/ISonneMerkleDistributor.sol"; +import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -/// @title Sonne Finance Merkle tree-based rewards distributor -/// @notice Contract to distribute rewards on BASE network to Sonne Finance Optimism stakers -contract SonneMerkleDistributor is - ReentrancyGuard, - Ownable, - ISonneMerkleDistributor -{ - using SafeERC20 for IERC20; - - struct Reward { - uint256 balance; // amount of reward tokens held in this reward - bytes32 merkleRoot; // root of claims merkle tree - uint256 withdrawUnlockTime; // time after which owner can withdraw remaining rewards - uint256 ratio; // ratio of rewards to be distributed per one staked token on OP - mapping(bytes32 => bool) leafClaimed; // mapping of leafes that already claimed - } +interface ISonneMerkleDistributor { + event NewMerkle( + address indexed creator, + address indexed rewardToken, + uint256 amount, + bytes32 indexed merkleRoot, + uint256 blockNr, + uint256 withdrawUnlockTime + ); + event MerkleFundUpdate( + address indexed funder, + bytes32 indexed merkleRoot, + uint256 blockNr, + uint256 amount, + bool withdrawal + ); + event MerkleClaim(address indexed claimer, address indexed rewardToken, uint256 indexed blockNr, uint256 amount); - IERC20 public immutable rewardToken; - uint256[] public rewards; // a list of all rewards + function rewardToken() external view returns (IERC20); - mapping(uint256 => Reward) public Rewards; // mapping between blockNumber => Reward - mapping(address => address) public delegatorAddresses; // mapping to allow msg.sender to claim on behalf of a delegators address + function Rewards( + uint256 blockNumber + ) external view returns (uint256 balance, bytes32 merkleRoot, uint256 withdrawUnlockTime, uint256 ratio); - /// @notice Contract constructor to initialize rewardToken - /// @param _rewardToken The reward token to be distributed - constructor(IERC20 _rewardToken) { - require(address(_rewardToken) != address(0), "Token cannot be zero"); - rewardToken = _rewardToken; - } + function delegatorAddresses(address _delegator) external view returns (address originalRecipient); - /// @notice Sets a delegator address for a given recipient - /// @param _recipient original eligible recipient address - /// @param _delegator The address that sould claim on behalf of the owner - function setDelegator( - address _recipient, - address _delegator - ) external onlyOwner { - require( - _recipient != address(0) && _delegator != address(0), - "Invalid address provided" - ); - delegatorAddresses[_delegator] = _recipient; - } + function setDelegator(address _recipient, address _delegator) external; - /// @notice Creates a new Reward struct for a rewards distribution - /// @param amount The amount of reward tokens to deposit - /// @param merkleRoot The merkle root of the distribution tree - /// @param blockNumber The block number for the Reward - /// @param withdrawUnlockTime The timestamp after which withdrawals by owner are allowed - /// @param totalStakedBalance Total staked balance of the merkleRoot (computed off-chain) function addReward( uint256 amount, bytes32 merkleRoot, uint256 blockNumber, uint256 withdrawUnlockTime, uint256 totalStakedBalance - ) external onlyOwner { - require(merkleRoot != bytes32(0), "Merkle root cannot be zero"); - - // creates a new reward struct tied to the blocknumber the merkleProof was created at - Reward storage reward = Rewards[blockNumber]; - - require( - reward.merkleRoot == bytes32(0), - "Merkle root was already posted" - ); - uint256 balance = rewardToken.balanceOf(msg.sender); - require( - amount > 0 && amount <= balance, - "Invalid amount or insufficient balance" - ); - - // transfer rewardToken from the distributor to the contract - rewardToken.safeTransferFrom(msg.sender, address(this), amount); - - // record Reward in stable storage - reward.balance = amount; - reward.merkleRoot = merkleRoot; - reward.withdrawUnlockTime = withdrawUnlockTime; - reward.ratio = (amount * 1e18) / (totalStakedBalance); - rewards.push(blockNumber); - emit NewMerkle( - msg.sender, - address(rewardToken), - amount, - merkleRoot, - blockNumber, - withdrawUnlockTime - ); - } - - /// @notice Allows to withdraw available funds to owner after unlock time - /// @param blockNumber The block number for the Reward - /// @param amount The amount to withdraw - function withdrawFunds( - uint256 blockNumber, - uint256 amount - ) external onlyOwner { - Reward storage reward = Rewards[blockNumber]; - require( - block.timestamp >= reward.withdrawUnlockTime, - "Rewards may not be withdrawn" - ); - require(amount <= reward.balance, "Insufficient balance"); - - // update Rewards record - reward.balance = reward.balance -= amount; - - // transfer rewardToken back to owner - rewardToken.safeTransfer(msg.sender, amount); - emit MerkleFundUpdate( - msg.sender, - reward.merkleRoot, - blockNumber, - amount, - true - ); - } - - /// @notice Claims the specified amount for an account if valid - /// @dev Checks proofs and claims tracking before transferring rewardTokens - /// @param blockNumber The block number for the Reward - /// @param proof The merkle proof for the claim - function claim( - uint256 blockNumber, - bytes[] calldata proof - ) external nonReentrant { - Reward storage reward = Rewards[blockNumber]; - require(reward.merkleRoot != bytes32(0), "Reward not found"); + ) external; - // Check if the delegatorAddresses includes the account - // The delegatorAddresses mapping allows for an account to delegate its claim ability to another address - // This can be useful in scenarios where the target recipient might not have the ability to directly interact - // with the BASE network contract (e.g. a smart contract with a different address) - address recipient = delegatorAddresses[msg.sender] != address(0) - ? delegatorAddresses[msg.sender] - : msg.sender; + function withdrawFunds(uint256 blockNumber, uint256 amount) external; - // Assuming slotNr is 2 as per your previous function - bytes32 key = keccak256(abi.encode(recipient, uint256(2))); - - //Get the amount of the key from the merkel tree - uint256 amount = _getValueFromMerkleTree(reward.merkleRoot, key, proof); - - // calculate the reward based on the ratio - uint256 rewardAmount = (amount * reward.ratio) / 1e18; // TODO check if there is a loss of precision possible here - - require( - reward.balance >= rewardAmount, - "Claim under-funded by funder." - ); - require( - Rewards[blockNumber].leafClaimed[key] == false, - "Already claimed" - ); - - // marks the leaf as claimed - reward.leafClaimed[key] = true; - - // Subtract the rewardAmount, not the amount - reward.balance = reward.balance - rewardAmount; - - //Send reward tokens to the recipient - rewardToken.safeTransfer(recipient, rewardAmount); - - emit MerkleClaim( - recipient, - address(rewardToken), - blockNumber, - rewardAmount - ); - } - - /// @notice Checks if a claim is valid and claimable - /// @param blockNumber The block number for the Reward - /// @param account The address of the account claiming - /// @param proof The merkle proof for the claim - /// @return A bool indicating if the claim is valid and claimable - function isClaimable( - uint256 blockNumber, - address account, - bytes[] calldata proof - ) external view returns (bool) { - bytes32 merkleRoot = Rewards[blockNumber].merkleRoot; - - // At the staking contract, the balances are stored in a mapping (address => uint256) at storage slot 2 - bytes32 leaf = keccak256(abi.encode(account, uint256(2))); - - if (merkleRoot == 0) return false; - return - !Rewards[blockNumber].leafClaimed[leaf] && - _getValueFromMerkleTree(merkleRoot, leaf, proof) > 0; - } - - /// @dev Uses SecureMerkleTrie Library to extract the value from the Merkle proof provided by the user - /// @param merkleRoot the merkle root - /// @param key the key of the leaf => keccak256(address,2) - /// @return result The converted uint256 value as stored in the slot on OP - function _getValueFromMerkleTree( - bytes32 merkleRoot, - bytes32 key, - bytes[] calldata proof - ) internal pure returns (uint256 result) { - // Uses SecureMerkleTrie Library to extract the value from the Merkle proof provided by the user - // Reverts if Merkle proof verification fails - bytes memory data = RLPReader.readBytes( - SecureMerkleTrie.get(abi.encodePacked(key), proof, merkleRoot) - ); + function claim(uint256 blockNumber, bytes[] calldata proof) external; - for (uint256 i = 0; i < data.length; i++) { - result = result * 256 + uint8(data[i]); - } - } + function isClaimable(uint256 blockNumber, address account, bytes[] calldata proof) external view returns (bool); } diff --git a/crosschain-rewards/deploy/00-sonne-merkle-distributor.base.ts b/crosschain-rewards/deploy/00-sonne-merkle-distributor.base.ts new file mode 100644 index 0000000..558d433 --- /dev/null +++ b/crosschain-rewards/deploy/00-sonne-merkle-distributor.base.ts @@ -0,0 +1,22 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; + +const func: DeployFunction = async ({ + getNamedAccounts, + deployments: { deploy }, + ethers, + network, +}: HardhatRuntimeEnvironment) => { + const { deployer } = await getNamedAccounts(); + + const sonne = '0x22a2488fE295047Ba13BD8cCCdBC8361DBD8cf7c'; + + const distributorDeploy = await deploy('SonneMerkleDistributor', { + from: deployer, + log: true, + contract: 'contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor', + args: [sonne], + }); +}; + +export default func; diff --git a/crosschain-rewards/deploy/01-usdc-merkle-distributor.base copy.ts b/crosschain-rewards/deploy/01-usdc-merkle-distributor.base copy.ts new file mode 100644 index 0000000..65e4424 --- /dev/null +++ b/crosschain-rewards/deploy/01-usdc-merkle-distributor.base copy.ts @@ -0,0 +1,22 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; + +const func: DeployFunction = async ({ + getNamedAccounts, + deployments: { deploy }, + ethers, + network, +}: HardhatRuntimeEnvironment) => { + const { deployer } = await getNamedAccounts(); + + const usdc = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'; + + const distributorDeploy = await deploy('UsdcMerkleDistributor', { + from: deployer, + log: true, + contract: 'contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor', + args: [usdc], + }); +}; + +export default func; diff --git a/crosschain-rewards/deploy/02-aero-merkle-distributor.base.ts b/crosschain-rewards/deploy/02-aero-merkle-distributor.base.ts new file mode 100644 index 0000000..084530c --- /dev/null +++ b/crosschain-rewards/deploy/02-aero-merkle-distributor.base.ts @@ -0,0 +1,22 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; + +const func: DeployFunction = async ({ + getNamedAccounts, + deployments: { deploy }, + ethers, + network, +}: HardhatRuntimeEnvironment) => { + const { deployer } = await getNamedAccounts(); + + const aero = '0x940181a94A35A4569E4529A3CDfB74e38FD98631'; + + const distributorDeploy = await deploy('AeroMerkleDistributor', { + from: deployer, + log: true, + contract: 'contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor', + args: [aero], + }); +}; + +export default func; diff --git a/crosschain-rewards/deployments/base/.chainId b/crosschain-rewards/deployments/base/.chainId new file mode 100644 index 0000000..2a0c263 --- /dev/null +++ b/crosschain-rewards/deployments/base/.chainId @@ -0,0 +1 @@ +8453 \ No newline at end of file diff --git a/crosschain-rewards/deployments/base/SonneMerkleDistributor.json b/crosschain-rewards/deployments/base/SonneMerkleDistributor.json new file mode 100644 index 0000000..58bdb8f --- /dev/null +++ b/crosschain-rewards/deployments/base/SonneMerkleDistributor.json @@ -0,0 +1,643 @@ +{ + "address": "0x0B4db67FaA6c6ab179C0942866AE89cC6dc3d8d4", + "abi": [ + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_rewardToken", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "claimer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "blockNr", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "MerkleClaim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "funder", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "merkleRoot", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "blockNr", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "withdrawal", + "type": "bool" + } + ], + "name": "MerkleFundUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "merkleRoot", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "blockNr", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "withdrawUnlockTime", + "type": "uint256" + } + ], + "name": "NewMerkle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "Rewards", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "merkleRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "withdrawUnlockTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ratio", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "merkleRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "withdrawUnlockTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalStakedBalance", + "type": "uint256" + } + ], + "name": "addReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "bytes[]", + "name": "proof", + "type": "bytes[]" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "delegatorAddresses", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes[]", + "name": "proof", + "type": "bytes[]" + } + ], + "name": "isClaimable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "address", + "name": "_delegator", + "type": "address" + } + ], + "name": "setDelegator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x2bf119705ff0f6acf2d4c37410ec4a7368959ed0db8fda3822419cf443256007", + "receipt": { + "to": null, + "from": "0xFb59Ce8986943163F14C590755b29dB2998F2322", + "contractAddress": "0x0B4db67FaA6c6ab179C0942866AE89cC6dc3d8d4", + "transactionIndex": 8, + "gasUsed": "2776101", + "logsBloom": "0x00000000000000000000000000000001000000100000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000001000000000000000000000000000000000000020000020000000000000800000000000000000000000000000000400000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x26df18c0966bb198c100245f21387cddc4ad6989c742da0c1cfdbc3c45661b8f", + "transactionHash": "0x2bf119705ff0f6acf2d4c37410ec4a7368959ed0db8fda3822419cf443256007", + "logs": [ + { + "transactionIndex": 8, + "blockNumber": 4220112, + "transactionHash": "0x2bf119705ff0f6acf2d4c37410ec4a7368959ed0db8fda3822419cf443256007", + "address": "0x0B4db67FaA6c6ab179C0942866AE89cC6dc3d8d4", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000fb59ce8986943163f14c590755b29db2998f2322" + ], + "data": "0x", + "logIndex": 18, + "blockHash": "0x26df18c0966bb198c100245f21387cddc4ad6989c742da0c1cfdbc3c45661b8f" + } + ], + "blockNumber": 4220112, + "cumulativeGasUsed": "3564220", + "status": 1, + "byzantium": true + }, + "args": [ + "0x22a2488fE295047Ba13BD8cCCdBC8361DBD8cf7c" + ], + "numDeployments": 1, + "solcInputHash": "30087f7fee47449a419e52a71b53a636", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"_rewardToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"claimer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNr\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"MerkleClaim\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"funder\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNr\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"withdrawal\",\"type\":\"bool\"}],\"name\":\"MerkleFundUpdate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNr\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"withdrawUnlockTime\",\"type\":\"uint256\"}],\"name\":\"NewMerkle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"Rewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"withdrawUnlockTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ratio\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"withdrawUnlockTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalStakedBalance\",\"type\":\"uint256\"}],\"name\":\"addReward\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"proof\",\"type\":\"bytes[]\"}],\"name\":\"claim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"delegatorAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes[]\",\"name\":\"proof\",\"type\":\"bytes[]\"}],\"name\":\"isClaimable\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardToken\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"rewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_delegator\",\"type\":\"address\"}],\"name\":\"setDelegator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addReward(uint256,bytes32,uint256,uint256,uint256)\":{\"params\":{\"amount\":\"The amount of reward tokens to deposit\",\"blockNumber\":\"The block number for the Reward\",\"merkleRoot\":\"The merkle root of the distribution tree\",\"totalStakedBalance\":\"Total staked balance of the merkleRoot (computed off-chain)\",\"withdrawUnlockTime\":\"The timestamp after which withdrawals by owner are allowed\"}},\"claim(uint256,bytes[])\":{\"details\":\"Checks proofs and claims tracking before transferring rewardTokens\",\"params\":{\"blockNumber\":\"The block number for the Reward\",\"proof\":\"The merkle proof for the claim\"}},\"constructor\":{\"params\":{\"_rewardToken\":\"The reward token to be distributed\"}},\"isClaimable(uint256,address,bytes[])\":{\"params\":{\"account\":\"The address of the account claiming\",\"blockNumber\":\"The block number for the Reward\",\"proof\":\"The merkle proof for the claim\"},\"returns\":{\"_0\":\"A bool indicating if the claim is valid and claimable\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setDelegator(address,address)\":{\"params\":{\"_delegator\":\"The address that sould claim on behalf of the owner\",\"_recipient\":\"original eligible recipient address\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"withdrawFunds(uint256,uint256)\":{\"params\":{\"amount\":\"The amount to withdraw\",\"blockNumber\":\"The block number for the Reward\"}}},\"title\":\"Sonne Finance Merkle tree-based rewards distributor\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addReward(uint256,bytes32,uint256,uint256,uint256)\":{\"notice\":\"Creates a new Reward struct for a rewards distribution\"},\"claim(uint256,bytes[])\":{\"notice\":\"Claims the specified amount for an account if valid\"},\"constructor\":{\"notice\":\"Contract constructor to initialize rewardToken\"},\"isClaimable(uint256,address,bytes[])\":{\"notice\":\"Checks if a claim is valid and claimable\"},\"setDelegator(address,address)\":{\"notice\":\"Sets a delegator address for a given recipient\"},\"withdrawFunds(uint256,uint256)\":{\"notice\":\"Allows to withdraw available funds to owner after unlock time\"}},\"notice\":\"Contract to distribute rewards on BASE network to Sonne Finance Optimism stakers\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/SonneMerkleDistributor.sol\":\"SonneMerkleDistributor\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/libraries/Bytes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title Bytes\\n/// @notice Bytes is a library for manipulating byte arrays.\\nlibrary Bytes {\\n /// @custom:attribution https://github.com/GNSPS/solidity-bytes-utils\\n /// @notice Slices a byte array with a given starting index and length. Returns a new byte array\\n /// as opposed to a pointer to the original array. Will throw if trying to slice more\\n /// bytes than exist in the array.\\n /// @param _bytes Byte array to slice.\\n /// @param _start Starting index of the slice.\\n /// @param _length Length of the slice.\\n /// @return Slice of the input byte array.\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n ) internal pure returns (bytes memory) {\\n unchecked {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_start + _length >= _start, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n }\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n /// @notice Slices a byte array with a given starting index up to the end of the original byte\\n /// array. Returns a new array rathern than a pointer to the original.\\n /// @param _bytes Byte array to slice.\\n /// @param _start Starting index of the slice.\\n /// @return Slice of the input byte array.\\n function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) {\\n if (_start >= _bytes.length) {\\n return bytes(\\\"\\\");\\n }\\n return slice(_bytes, _start, _bytes.length - _start);\\n }\\n\\n /// @notice Converts a byte array into a nibble array by splitting each byte into two nibbles.\\n /// Resulting nibble array will be exactly twice as long as the input byte array.\\n /// @param _bytes Input byte array to convert.\\n /// @return Resulting nibble array.\\n function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) {\\n bytes memory _nibbles;\\n assembly {\\n // Grab a free memory offset for the new array\\n _nibbles := mload(0x40)\\n\\n // Load the length of the passed bytes array from memory\\n let bytesLength := mload(_bytes)\\n\\n // Calculate the length of the new nibble array\\n // This is the length of the input array times 2\\n let nibblesLength := shl(0x01, bytesLength)\\n\\n // Update the free memory pointer to allocate memory for the new array.\\n // To do this, we add the length of the new array + 32 bytes for the array length\\n // rounded up to the nearest 32 byte boundary to the current free memory pointer.\\n mstore(0x40, add(_nibbles, and(not(0x1F), add(nibblesLength, 0x3F))))\\n\\n // Store the length of the new array in memory\\n mstore(_nibbles, nibblesLength)\\n\\n // Store the memory offset of the _bytes array's contents on the stack\\n let bytesStart := add(_bytes, 0x20)\\n\\n // Store the memory offset of the nibbles array's contents on the stack\\n let nibblesStart := add(_nibbles, 0x20)\\n\\n // Loop through each byte in the input array\\n for {\\n let i := 0x00\\n } lt(i, bytesLength) {\\n i := add(i, 0x01)\\n } {\\n // Get the starting offset of the next 2 bytes in the nibbles array\\n let offset := add(nibblesStart, shl(0x01, i))\\n // Load the byte at the current index within the `_bytes` array\\n let b := byte(0x00, mload(add(bytesStart, i)))\\n\\n // Pull out the first nibble and store it in the new array\\n mstore8(offset, shr(0x04, b))\\n // Pull out the second nibble and store it in the new array\\n mstore8(add(offset, 0x01), and(b, 0x0F))\\n }\\n }\\n return _nibbles;\\n }\\n\\n /// @notice Compares two byte arrays by comparing their keccak256 hashes.\\n /// @param _bytes First byte array to compare.\\n /// @param _other Second byte array to compare.\\n /// @return True if the two byte arrays are equal, false otherwise.\\n function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) {\\n return keccak256(_bytes) == keccak256(_other);\\n }\\n}\\n\",\"keccak256\":\"0x6fa7ba368cfee95b16b177c92745583736ad623befb81c8ae98ce020e670ce44\",\"license\":\"MIT\"},\"@eth-optimism/contracts-bedrock/contracts/libraries/rlp/RLPReader.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.8;\\n\\n/**\\n * @custom:attribution https://github.com/hamdiallam/Solidity-RLP\\n * @title RLPReader\\n * @notice RLPReader is a library for parsing RLP-encoded byte arrays into Solidity types. Adapted\\n * from Solidity-RLP (https://github.com/hamdiallam/Solidity-RLP) by Hamdi Allam with\\n * various tweaks to improve readability.\\n */\\nlibrary RLPReader {\\n /**\\n * Custom pointer type to avoid confusion between pointers and uint256s.\\n */\\n type MemoryPointer is uint256;\\n\\n /**\\n * @notice RLP item types.\\n *\\n * @custom:value DATA_ITEM Represents an RLP data item (NOT a list).\\n * @custom:value LIST_ITEM Represents an RLP list item.\\n */\\n enum RLPItemType {\\n DATA_ITEM,\\n LIST_ITEM\\n }\\n\\n /**\\n * @notice Struct representing an RLP item.\\n *\\n * @custom:field length Length of the RLP item.\\n * @custom:field ptr Pointer to the RLP item in memory.\\n */\\n struct RLPItem {\\n uint256 length;\\n MemoryPointer ptr;\\n }\\n\\n /**\\n * @notice Max list length that this library will accept.\\n */\\n uint256 internal constant MAX_LIST_LENGTH = 32;\\n\\n /**\\n * @notice Converts bytes to a reference to memory position and length.\\n *\\n * @param _in Input bytes to convert.\\n *\\n * @return Output memory reference.\\n */\\n function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory) {\\n // Empty arrays are not RLP items.\\n require(\\n _in.length > 0,\\n \\\"RLPReader: length of an RLP item must be greater than zero to be decodable\\\"\\n );\\n\\n MemoryPointer ptr;\\n assembly {\\n ptr := add(_in, 32)\\n }\\n\\n return RLPItem({ length: _in.length, ptr: ptr });\\n }\\n\\n /**\\n * @notice Reads an RLP list value into a list of RLP items.\\n *\\n * @param _in RLP list value.\\n *\\n * @return Decoded RLP list items.\\n */\\n function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) {\\n (uint256 listOffset, uint256 listLength, RLPItemType itemType) = _decodeLength(_in);\\n\\n require(\\n itemType == RLPItemType.LIST_ITEM,\\n \\\"RLPReader: decoded item type for list is not a list item\\\"\\n );\\n\\n require(\\n listOffset + listLength == _in.length,\\n \\\"RLPReader: list item has an invalid data remainder\\\"\\n );\\n\\n // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by\\n // writing to the length. Since we can't know the number of RLP items without looping over\\n // the entire input, we'd have to loop twice to accurately size this array. It's easier to\\n // simply set a reasonable maximum list length and decrease the size before we finish.\\n RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH);\\n\\n uint256 itemCount = 0;\\n uint256 offset = listOffset;\\n while (offset < _in.length) {\\n (uint256 itemOffset, uint256 itemLength, ) = _decodeLength(\\n RLPItem({\\n length: _in.length - offset,\\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\\n })\\n );\\n\\n // We don't need to check itemCount < out.length explicitly because Solidity already\\n // handles this check on our behalf, we'd just be wasting gas.\\n out[itemCount] = RLPItem({\\n length: itemLength + itemOffset,\\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\\n });\\n\\n itemCount += 1;\\n offset += itemOffset + itemLength;\\n }\\n\\n // Decrease the array size to match the actual item count.\\n assembly {\\n mstore(out, itemCount)\\n }\\n\\n return out;\\n }\\n\\n /**\\n * @notice Reads an RLP list value into a list of RLP items.\\n *\\n * @param _in RLP list value.\\n *\\n * @return Decoded RLP list items.\\n */\\n function readList(bytes memory _in) internal pure returns (RLPItem[] memory) {\\n return readList(toRLPItem(_in));\\n }\\n\\n /**\\n * @notice Reads an RLP bytes value into bytes.\\n *\\n * @param _in RLP bytes value.\\n *\\n * @return Decoded bytes.\\n */\\n function readBytes(RLPItem memory _in) internal pure returns (bytes memory) {\\n (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);\\n\\n require(\\n itemType == RLPItemType.DATA_ITEM,\\n \\\"RLPReader: decoded item type for bytes is not a data item\\\"\\n );\\n\\n require(\\n _in.length == itemOffset + itemLength,\\n \\\"RLPReader: bytes value contains an invalid remainder\\\"\\n );\\n\\n return _copy(_in.ptr, itemOffset, itemLength);\\n }\\n\\n /**\\n * @notice Reads an RLP bytes value into bytes.\\n *\\n * @param _in RLP bytes value.\\n *\\n * @return Decoded bytes.\\n */\\n function readBytes(bytes memory _in) internal pure returns (bytes memory) {\\n return readBytes(toRLPItem(_in));\\n }\\n\\n /**\\n * @notice Reads the raw bytes of an RLP item.\\n *\\n * @param _in RLP item to read.\\n *\\n * @return Raw RLP bytes.\\n */\\n function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory) {\\n return _copy(_in.ptr, 0, _in.length);\\n }\\n\\n /**\\n * @notice Decodes the length of an RLP item.\\n *\\n * @param _in RLP item to decode.\\n *\\n * @return Offset of the encoded data.\\n * @return Length of the encoded data.\\n * @return RLP item type (LIST_ITEM or DATA_ITEM).\\n */\\n function _decodeLength(RLPItem memory _in)\\n private\\n pure\\n returns (\\n uint256,\\n uint256,\\n RLPItemType\\n )\\n {\\n // Short-circuit if there's nothing to decode, note that we perform this check when\\n // the user creates an RLP item via toRLPItem, but it's always possible for them to bypass\\n // that function and create an RLP item directly. So we need to check this anyway.\\n require(\\n _in.length > 0,\\n \\\"RLPReader: length of an RLP item must be greater than zero to be decodable\\\"\\n );\\n\\n MemoryPointer ptr = _in.ptr;\\n uint256 prefix;\\n assembly {\\n prefix := byte(0, mload(ptr))\\n }\\n\\n if (prefix <= 0x7f) {\\n // Single byte.\\n return (0, 1, RLPItemType.DATA_ITEM);\\n } else if (prefix <= 0xb7) {\\n // Short string.\\n\\n // slither-disable-next-line variable-scope\\n uint256 strLen = prefix - 0x80;\\n\\n require(\\n _in.length > strLen,\\n \\\"RLPReader: length of content must be greater than string length (short string)\\\"\\n );\\n\\n bytes1 firstByteOfContent;\\n assembly {\\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\\n }\\n\\n require(\\n strLen != 1 || firstByteOfContent >= 0x80,\\n \\\"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\\\"\\n );\\n\\n return (1, strLen, RLPItemType.DATA_ITEM);\\n } else if (prefix <= 0xbf) {\\n // Long string.\\n uint256 lenOfStrLen = prefix - 0xb7;\\n\\n require(\\n _in.length > lenOfStrLen,\\n \\\"RLPReader: length of content must be > than length of string length (long string)\\\"\\n );\\n\\n bytes1 firstByteOfContent;\\n assembly {\\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\\n }\\n\\n require(\\n firstByteOfContent != 0x00,\\n \\\"RLPReader: length of content must not have any leading zeros (long string)\\\"\\n );\\n\\n uint256 strLen;\\n assembly {\\n strLen := shr(sub(256, mul(8, lenOfStrLen)), mload(add(ptr, 1)))\\n }\\n\\n require(\\n strLen > 55,\\n \\\"RLPReader: length of content must be greater than 55 bytes (long string)\\\"\\n );\\n\\n require(\\n _in.length > lenOfStrLen + strLen,\\n \\\"RLPReader: length of content must be greater than total length (long string)\\\"\\n );\\n\\n return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM);\\n } else if (prefix <= 0xf7) {\\n // Short list.\\n // slither-disable-next-line variable-scope\\n uint256 listLen = prefix - 0xc0;\\n\\n require(\\n _in.length > listLen,\\n \\\"RLPReader: length of content must be greater than list length (short list)\\\"\\n );\\n\\n return (1, listLen, RLPItemType.LIST_ITEM);\\n } else {\\n // Long list.\\n uint256 lenOfListLen = prefix - 0xf7;\\n\\n require(\\n _in.length > lenOfListLen,\\n \\\"RLPReader: length of content must be > than length of list length (long list)\\\"\\n );\\n\\n bytes1 firstByteOfContent;\\n assembly {\\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\\n }\\n\\n require(\\n firstByteOfContent != 0x00,\\n \\\"RLPReader: length of content must not have any leading zeros (long list)\\\"\\n );\\n\\n uint256 listLen;\\n assembly {\\n listLen := shr(sub(256, mul(8, lenOfListLen)), mload(add(ptr, 1)))\\n }\\n\\n require(\\n listLen > 55,\\n \\\"RLPReader: length of content must be greater than 55 bytes (long list)\\\"\\n );\\n\\n require(\\n _in.length > lenOfListLen + listLen,\\n \\\"RLPReader: length of content must be greater than total length (long list)\\\"\\n );\\n\\n return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM);\\n }\\n }\\n\\n /**\\n * @notice Copies the bytes from a memory location.\\n *\\n * @param _src Pointer to the location to read from.\\n * @param _offset Offset to start reading from.\\n * @param _length Number of bytes to read.\\n *\\n * @return Copied bytes.\\n */\\n function _copy(\\n MemoryPointer _src,\\n uint256 _offset,\\n uint256 _length\\n ) private pure returns (bytes memory) {\\n bytes memory out = new bytes(_length);\\n if (_length == 0) {\\n return out;\\n }\\n\\n // Mostly based on Solidity's copy_memory_to_memory:\\n // solhint-disable max-line-length\\n // https://github.com/ethereum/solidity/blob/34dd30d71b4da730488be72ff6af7083cf2a91f6/libsolidity/codegen/YulUtilFunctions.cpp#L102-L114\\n uint256 src = MemoryPointer.unwrap(_src) + _offset;\\n assembly {\\n let dest := add(out, 32)\\n let i := 0\\n for {\\n\\n } lt(i, _length) {\\n i := add(i, 32)\\n } {\\n mstore(add(dest, i), mload(add(src, i)))\\n }\\n\\n if gt(i, _length) {\\n mstore(add(dest, _length), 0)\\n }\\n }\\n\\n return out;\\n }\\n}\\n\",\"keccak256\":\"0x50763c897f0fe84cb067985ec4d7c5721ce9004a69cf0327f96f8982ee8ca412\",\"license\":\"MIT\"},\"@eth-optimism/contracts-bedrock/contracts/libraries/trie/MerkleTrie.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { Bytes } from \\\"../Bytes.sol\\\";\\nimport { RLPReader } from \\\"../rlp/RLPReader.sol\\\";\\n\\n/**\\n * @title MerkleTrie\\n * @notice MerkleTrie is a small library for verifying standard Ethereum Merkle-Patricia trie\\n * inclusion proofs. By default, this library assumes a hexary trie. One can change the\\n * trie radix constant to support other trie radixes.\\n */\\nlibrary MerkleTrie {\\n /**\\n * @notice Struct representing a node in the trie.\\n *\\n * @custom:field encoded The RLP-encoded node.\\n * @custom:field decoded The RLP-decoded node.\\n */\\n struct TrieNode {\\n bytes encoded;\\n RLPReader.RLPItem[] decoded;\\n }\\n\\n /**\\n * @notice Determines the number of elements per branch node.\\n */\\n uint256 internal constant TREE_RADIX = 16;\\n\\n /**\\n * @notice Branch nodes have TREE_RADIX elements and one value element.\\n */\\n uint256 internal constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;\\n\\n /**\\n * @notice Leaf nodes and extension nodes have two elements, a `path` and a `value`.\\n */\\n uint256 internal constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;\\n\\n /**\\n * @notice Prefix for even-nibbled extension node paths.\\n */\\n uint8 internal constant PREFIX_EXTENSION_EVEN = 0;\\n\\n /**\\n * @notice Prefix for odd-nibbled extension node paths.\\n */\\n uint8 internal constant PREFIX_EXTENSION_ODD = 1;\\n\\n /**\\n * @notice Prefix for even-nibbled leaf node paths.\\n */\\n uint8 internal constant PREFIX_LEAF_EVEN = 2;\\n\\n /**\\n * @notice Prefix for odd-nibbled leaf node paths.\\n */\\n uint8 internal constant PREFIX_LEAF_ODD = 3;\\n\\n /**\\n * @notice Verifies a proof that a given key/value pair is present in the trie.\\n *\\n * @param _key Key of the node to search for, as a hex string.\\n * @param _value Value of the node to search for, as a hex string.\\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\\n * nodes that make a path down to the target node.\\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\\n * correctly constructed.\\n *\\n * @return Whether or not the proof is valid.\\n */\\n function verifyInclusionProof(\\n bytes memory _key,\\n bytes memory _value,\\n bytes[] memory _proof,\\n bytes32 _root\\n ) internal pure returns (bool) {\\n return Bytes.equal(_value, get(_key, _proof, _root));\\n }\\n\\n /**\\n * @notice Retrieves the value associated with a given key.\\n *\\n * @param _key Key to search for, as hex bytes.\\n * @param _proof Merkle trie inclusion proof for the key.\\n * @param _root Known root of the Merkle trie.\\n *\\n * @return Value of the key if it exists.\\n */\\n function get(\\n bytes memory _key,\\n bytes[] memory _proof,\\n bytes32 _root\\n ) internal pure returns (bytes memory) {\\n require(_key.length > 0, \\\"MerkleTrie: empty key\\\");\\n\\n TrieNode[] memory proof = _parseProof(_proof);\\n bytes memory key = Bytes.toNibbles(_key);\\n bytes memory currentNodeID = abi.encodePacked(_root);\\n uint256 currentKeyIndex = 0;\\n\\n // Proof is top-down, so we start at the first element (root).\\n for (uint256 i = 0; i < proof.length; i++) {\\n TrieNode memory currentNode = proof[i];\\n\\n // Key index should never exceed total key length or we'll be out of bounds.\\n require(\\n currentKeyIndex <= key.length,\\n \\\"MerkleTrie: key index exceeds total key length\\\"\\n );\\n\\n if (currentKeyIndex == 0) {\\n // First proof element is always the root node.\\n require(\\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\\n \\\"MerkleTrie: invalid root hash\\\"\\n );\\n } else if (currentNode.encoded.length >= 32) {\\n // Nodes 32 bytes or larger are hashed inside branch nodes.\\n require(\\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\\n \\\"MerkleTrie: invalid large internal hash\\\"\\n );\\n } else {\\n // Nodes smaller than 32 bytes aren't hashed.\\n require(\\n Bytes.equal(currentNode.encoded, currentNodeID),\\n \\\"MerkleTrie: invalid internal node hash\\\"\\n );\\n }\\n\\n if (currentNode.decoded.length == BRANCH_NODE_LENGTH) {\\n if (currentKeyIndex == key.length) {\\n // Value is the last element of the decoded list (for branch nodes). There's\\n // some ambiguity in the Merkle trie specification because bytes(0) is a\\n // valid value to place into the trie, but for branch nodes bytes(0) can exist\\n // even when the value wasn't explicitly placed there. Geth treats a value of\\n // bytes(0) as \\\"key does not exist\\\" and so we do the same.\\n bytes memory value = RLPReader.readBytes(currentNode.decoded[TREE_RADIX]);\\n require(\\n value.length > 0,\\n \\\"MerkleTrie: value length must be greater than zero (branch)\\\"\\n );\\n\\n // Extra proof elements are not allowed.\\n require(\\n i == proof.length - 1,\\n \\\"MerkleTrie: value node must be last node in proof (branch)\\\"\\n );\\n\\n return value;\\n } else {\\n // We're not at the end of the key yet.\\n // Figure out what the next node ID should be and continue.\\n uint8 branchKey = uint8(key[currentKeyIndex]);\\n RLPReader.RLPItem memory nextNode = currentNode.decoded[branchKey];\\n currentNodeID = _getNodeID(nextNode);\\n currentKeyIndex += 1;\\n }\\n } else if (currentNode.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) {\\n bytes memory path = _getNodePath(currentNode);\\n uint8 prefix = uint8(path[0]);\\n uint8 offset = 2 - (prefix % 2);\\n bytes memory pathRemainder = Bytes.slice(path, offset);\\n bytes memory keyRemainder = Bytes.slice(key, currentKeyIndex);\\n uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder);\\n\\n // Whether this is a leaf node or an extension node, the path remainder MUST be a\\n // prefix of the key remainder (or be equal to the key remainder) or the proof is\\n // considered invalid.\\n require(\\n pathRemainder.length == sharedNibbleLength,\\n \\\"MerkleTrie: path remainder must share all nibbles with key\\\"\\n );\\n\\n if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) {\\n // Prefix of 2 or 3 means this is a leaf node. For the leaf node to be valid,\\n // the key remainder must be exactly equal to the path remainder. We already\\n // did the necessary byte comparison, so it's more efficient here to check that\\n // the key remainder length equals the shared nibble length, which implies\\n // equality with the path remainder (since we already did the same check with\\n // the path remainder and the shared nibble length).\\n require(\\n keyRemainder.length == sharedNibbleLength,\\n \\\"MerkleTrie: key remainder must be identical to path remainder\\\"\\n );\\n\\n // Our Merkle Trie is designed specifically for the purposes of the Ethereum\\n // state trie. Empty values are not allowed in the state trie, so we can safely\\n // say that if the value is empty, the key should not exist and the proof is\\n // invalid.\\n bytes memory value = RLPReader.readBytes(currentNode.decoded[1]);\\n require(\\n value.length > 0,\\n \\\"MerkleTrie: value length must be greater than zero (leaf)\\\"\\n );\\n\\n // Extra proof elements are not allowed.\\n require(\\n i == proof.length - 1,\\n \\\"MerkleTrie: value node must be last node in proof (leaf)\\\"\\n );\\n\\n return value;\\n } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {\\n // Prefix of 0 or 1 means this is an extension node. We move onto the next node\\n // in the proof and increment the key index by the length of the path remainder\\n // which is equal to the shared nibble length.\\n currentNodeID = _getNodeID(currentNode.decoded[1]);\\n currentKeyIndex += sharedNibbleLength;\\n } else {\\n revert(\\\"MerkleTrie: received a node with an unknown prefix\\\");\\n }\\n } else {\\n revert(\\\"MerkleTrie: received an unparseable node\\\");\\n }\\n }\\n\\n revert(\\\"MerkleTrie: ran out of proof elements\\\");\\n }\\n\\n /**\\n * @notice Parses an array of proof elements into a new array that contains both the original\\n * encoded element and the RLP-decoded element.\\n *\\n * @param _proof Array of proof elements to parse.\\n *\\n * @return Proof parsed into easily accessible structs.\\n */\\n function _parseProof(bytes[] memory _proof) private pure returns (TrieNode[] memory) {\\n uint256 length = _proof.length;\\n TrieNode[] memory proof = new TrieNode[](length);\\n for (uint256 i = 0; i < length; ) {\\n proof[i] = TrieNode({ encoded: _proof[i], decoded: RLPReader.readList(_proof[i]) });\\n unchecked {\\n ++i;\\n }\\n }\\n return proof;\\n }\\n\\n /**\\n * @notice Picks out the ID for a node. Node ID is referred to as the \\\"hash\\\" within the\\n * specification, but nodes < 32 bytes are not actually hashed.\\n *\\n * @param _node Node to pull an ID for.\\n *\\n * @return ID for the node, depending on the size of its contents.\\n */\\n function _getNodeID(RLPReader.RLPItem memory _node) private pure returns (bytes memory) {\\n return _node.length < 32 ? RLPReader.readRawBytes(_node) : RLPReader.readBytes(_node);\\n }\\n\\n /**\\n * @notice Gets the path for a leaf or extension node.\\n *\\n * @param _node Node to get a path for.\\n *\\n * @return Node path, converted to an array of nibbles.\\n */\\n function _getNodePath(TrieNode memory _node) private pure returns (bytes memory) {\\n return Bytes.toNibbles(RLPReader.readBytes(_node.decoded[0]));\\n }\\n\\n /**\\n * @notice Utility; determines the number of nibbles shared between two nibble arrays.\\n *\\n * @param _a First nibble array.\\n * @param _b Second nibble array.\\n *\\n * @return Number of shared nibbles.\\n */\\n function _getSharedNibbleLength(bytes memory _a, bytes memory _b)\\n private\\n pure\\n returns (uint256)\\n {\\n uint256 shared;\\n uint256 max = (_a.length < _b.length) ? _a.length : _b.length;\\n for (; shared < max && _a[shared] == _b[shared]; ) {\\n unchecked {\\n ++shared;\\n }\\n }\\n return shared;\\n }\\n}\\n\",\"keccak256\":\"0xd27fc945d6dd2821636d840f3766f817823c8e9fbfdb87c2da7c73e4292d2f7f\",\"license\":\"MIT\"},\"@eth-optimism/contracts-bedrock/contracts/libraries/trie/SecureMerkleTrie.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/* Library Imports */\\nimport { MerkleTrie } from \\\"./MerkleTrie.sol\\\";\\n\\n/**\\n * @title SecureMerkleTrie\\n * @notice SecureMerkleTrie is a thin wrapper around the MerkleTrie library that hashes the input\\n * keys. Ethereum's state trie hashes input keys before storing them.\\n */\\nlibrary SecureMerkleTrie {\\n /**\\n * @notice Verifies a proof that a given key/value pair is present in the Merkle trie.\\n *\\n * @param _key Key of the node to search for, as a hex string.\\n * @param _value Value of the node to search for, as a hex string.\\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\\n * nodes that make a path down to the target node.\\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\\n * correctly constructed.\\n *\\n * @return Whether or not the proof is valid.\\n */\\n function verifyInclusionProof(\\n bytes memory _key,\\n bytes memory _value,\\n bytes[] memory _proof,\\n bytes32 _root\\n ) internal pure returns (bool) {\\n bytes memory key = _getSecureKey(_key);\\n return MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);\\n }\\n\\n /**\\n * @notice Retrieves the value associated with a given key.\\n *\\n * @param _key Key to search for, as hex bytes.\\n * @param _proof Merkle trie inclusion proof for the key.\\n * @param _root Known root of the Merkle trie.\\n *\\n * @return Value of the key if it exists.\\n */\\n function get(\\n bytes memory _key,\\n bytes[] memory _proof,\\n bytes32 _root\\n ) internal pure returns (bytes memory) {\\n bytes memory key = _getSecureKey(_key);\\n return MerkleTrie.get(key, _proof, _root);\\n }\\n\\n /**\\n * @notice Computes the hashed version of the input key.\\n *\\n * @param _key Key to hash.\\n *\\n * @return Hashed version of the key.\\n */\\n function _getSecureKey(bytes memory _key) private pure returns (bytes memory) {\\n return abi.encodePacked(keccak256(_key));\\n }\\n}\\n\",\"keccak256\":\"0x61b03a03779cb1f75cea3b88af16fdfd10629029b4b2d6be5238e71af8ef1b5f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling 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\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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 _nonReentrantBefore();\\n _;\\n _nonReentrantAfter();\\n }\\n\\n function _nonReentrantBefore() private {\\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n }\\n\\n function _nonReentrantAfter() private {\\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 /**\\n * @dev Returns true if the reentrancy guard is currently set to \\\"entered\\\", which indicates there is a\\n * `nonReentrant` function in the call stack.\\n */\\n function _reentrancyGuardEntered() internal view returns (bool) {\\n return _status == _ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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 * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, \\\"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(address target, bytes memory data, uint256 value) 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 (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or 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 _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\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\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts/SonneMerkleDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.19;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {SecureMerkleTrie} from \\\"@eth-optimism/contracts-bedrock/contracts/libraries/trie/SecureMerkleTrie.sol\\\";\\nimport {RLPReader} from \\\"@eth-optimism/contracts-bedrock/contracts/libraries/rlp/RLPReader.sol\\\";\\nimport {ISonneMerkleDistributor} from \\\"./interfaces/ISonneMerkleDistributor.sol\\\";\\n\\n/// @title Sonne Finance Merkle tree-based rewards distributor\\n/// @notice Contract to distribute rewards on BASE network to Sonne Finance Optimism stakers\\ncontract SonneMerkleDistributor is\\n ReentrancyGuard,\\n Ownable,\\n ISonneMerkleDistributor\\n{\\n using SafeERC20 for IERC20;\\n\\n struct Reward {\\n uint256 balance; // amount of reward tokens held in this reward\\n bytes32 merkleRoot; // root of claims merkle tree\\n uint256 withdrawUnlockTime; // time after which owner can withdraw remaining rewards\\n uint256 ratio; // ratio of rewards to be distributed per one staked token on OP\\n mapping(bytes32 => bool) leafClaimed; // mapping of leafes that already claimed\\n }\\n\\n IERC20 public immutable rewardToken;\\n uint256[] public rewards; // a list of all rewards\\n\\n mapping(uint256 => Reward) public Rewards; // mapping between blockNumber => Reward\\n mapping(address => address) public delegatorAddresses;\\n\\n /// mapping to allow msg.sender to claim on behalf of a delegators address\\n\\n /// @notice Contract constructor to initialize rewardToken\\n /// @param _rewardToken The reward token to be distributed\\n constructor(IERC20 _rewardToken) {\\n require(address(_rewardToken) != address(0), \\\"Token cannot be zero\\\");\\n rewardToken = _rewardToken;\\n }\\n\\n /// @notice Sets a delegator address for a given recipient\\n /// @param _recipient original eligible recipient address\\n /// @param _delegator The address that sould claim on behalf of the owner\\n function setDelegator(\\n address _recipient,\\n address _delegator\\n ) external onlyOwner {\\n require(\\n _recipient != address(0) && _delegator != address(0),\\n \\\"Invalid address provided\\\"\\n );\\n delegatorAddresses[_delegator] = _recipient;\\n }\\n\\n /// @notice Creates a new Reward struct for a rewards distribution\\n /// @param amount The amount of reward tokens to deposit\\n /// @param merkleRoot The merkle root of the distribution tree\\n /// @param blockNumber The block number for the Reward\\n /// @param withdrawUnlockTime The timestamp after which withdrawals by owner are allowed\\n /// @param totalStakedBalance Total staked balance of the merkleRoot (computed off-chain)\\n function addReward(\\n uint256 amount,\\n bytes32 merkleRoot,\\n uint256 blockNumber,\\n uint256 withdrawUnlockTime,\\n uint256 totalStakedBalance\\n ) external onlyOwner {\\n require(merkleRoot != bytes32(0), \\\"Merkle root cannot be zero\\\");\\n\\n // creates a new reward struct tied to the blocknumber the merkleProof was created at\\n Reward storage reward = Rewards[blockNumber];\\n\\n require(\\n reward.merkleRoot == bytes32(0),\\n \\\"Merkle root was already posted\\\"\\n );\\n uint256 balance = rewardToken.balanceOf(msg.sender);\\n require(\\n amount > 0 && amount <= balance,\\n \\\"Invalid amount or insufficient balance\\\"\\n );\\n\\n // transfer rewardToken from the distributor to the contract\\n rewardToken.safeTransferFrom(msg.sender, address(this), amount);\\n\\n // record Reward in stable storage\\n reward.balance = amount;\\n reward.merkleRoot = merkleRoot;\\n reward.withdrawUnlockTime = withdrawUnlockTime;\\n reward.ratio = (amount * 1e18) / (totalStakedBalance);\\n rewards.push(blockNumber);\\n emit NewMerkle(\\n msg.sender,\\n address(rewardToken),\\n amount,\\n merkleRoot,\\n blockNumber,\\n withdrawUnlockTime\\n );\\n }\\n\\n /// @notice Allows to withdraw available funds to owner after unlock time\\n /// @param blockNumber The block number for the Reward\\n /// @param amount The amount to withdraw\\n function withdrawFunds(\\n uint256 blockNumber,\\n uint256 amount\\n ) external onlyOwner {\\n Reward storage reward = Rewards[blockNumber];\\n require(\\n block.timestamp >= reward.withdrawUnlockTime,\\n \\\"Rewards may not be withdrawn\\\"\\n );\\n require(amount <= reward.balance, \\\"Insufficient balance\\\");\\n\\n // update Rewards record\\n reward.balance = reward.balance -= amount;\\n\\n // transfer rewardToken back to owner\\n rewardToken.safeTransfer(msg.sender, amount);\\n emit MerkleFundUpdate(\\n msg.sender,\\n reward.merkleRoot,\\n blockNumber,\\n amount,\\n true\\n );\\n }\\n\\n /// @notice Claims the specified amount for an account if valid\\n /// @dev Checks proofs and claims tracking before transferring rewardTokens\\n /// @param blockNumber The block number for the Reward\\n /// @param proof The merkle proof for the claim\\n function claim(\\n uint256 blockNumber,\\n bytes[] calldata proof\\n ) external nonReentrant {\\n Reward storage reward = Rewards[blockNumber];\\n require(reward.merkleRoot != bytes32(0), \\\"Reward not found\\\");\\n\\n // Check if the delegatorAddresses includes the account\\n // The delegatorAddresses mapping allows for an account to delegate its claim ability to another address\\n // This can be useful in scenarios where the target recipient might not have the ability to directly interact\\n // with the BASE network contract (e.g. a smart contract with a different address)\\n address recipient = delegatorAddresses[msg.sender] != address(0)\\n ? delegatorAddresses[msg.sender]\\n : msg.sender;\\n\\n // Assuming slotNr is 2 as per your previous function\\n bytes32 key = keccak256(abi.encode(recipient, uint256(2)));\\n\\n //Get the amount of the key from the merkel tree\\n uint256 amount = _getValueFromMerkleTree(reward.merkleRoot, key, proof);\\n\\n // calculate the reward based on the ratio\\n uint256 rewardAmount = (amount * reward.ratio) / 1e18; // TODO check if there is a loss of precision possible here\\n\\n require(\\n reward.balance >= rewardAmount,\\n \\\"Claim under-funded by funder.\\\"\\n );\\n require(\\n Rewards[blockNumber].leafClaimed[key] == false,\\n \\\"Already claimed\\\"\\n );\\n\\n // marks the leaf as claimed\\n reward.leafClaimed[key] = true;\\n\\n // Subtract the rewardAmount, not the amount\\n reward.balance = reward.balance - rewardAmount;\\n\\n //Send reward tokens to the recipient\\n rewardToken.safeTransfer(recipient, rewardAmount);\\n\\n emit MerkleClaim(\\n recipient,\\n address(rewardToken),\\n blockNumber,\\n rewardAmount\\n );\\n }\\n\\n /// @notice Checks if a claim is valid and claimable\\n /// @param blockNumber The block number for the Reward\\n /// @param account The address of the account claiming\\n /// @param proof The merkle proof for the claim\\n /// @return A bool indicating if the claim is valid and claimable\\n function isClaimable(\\n uint256 blockNumber,\\n address account,\\n bytes[] calldata proof\\n ) external view returns (bool) {\\n bytes32 merkleRoot = Rewards[blockNumber].merkleRoot;\\n\\n // At the staking contract, the balances are stored in a mapping (address => uint256) at storage slot 2\\n bytes32 leaf = keccak256(abi.encode(account, uint256(2)));\\n\\n if (merkleRoot == 0) return false;\\n return\\n !Rewards[blockNumber].leafClaimed[leaf] &&\\n _getValueFromMerkleTree(merkleRoot, leaf, proof) > 0;\\n }\\n\\n /// @dev Uses SecureMerkleTrie Library to extract the value from the Merkle proof provided by the user\\n /// @param merkleRoot the merkle root\\n /// @param key the key of the leaf => keccak256(address,2)\\n /// @return result The converted uint256 value as stored in the slot on OP\\n function _getValueFromMerkleTree(\\n bytes32 merkleRoot,\\n bytes32 key,\\n bytes[] calldata proof\\n ) internal pure returns (uint256 result) {\\n // Uses SecureMerkleTrie Library to extract the value from the Merkle proof provided by the user\\n // Reverts if Merkle proof verification fails\\n bytes memory data = RLPReader.readBytes(\\n SecureMerkleTrie.get(abi.encodePacked(key), proof, merkleRoot)\\n );\\n\\n for (uint256 i = 0; i < data.length; i++) {\\n result = result * 256 + uint8(data[i]);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x24a21883e5b5e69784f51f50a81ce2004026d1076058c0f2c035f4e6090969ed\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ISonneMerkleDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.19;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\n\\ninterface ISonneMerkleDistributor {\\n event NewMerkle(\\n address indexed creator,\\n address indexed rewardToken,\\n uint256 amount,\\n bytes32 indexed merkleRoot,\\n uint256 blockNr,\\n uint256 withdrawUnlockTime\\n );\\n event MerkleFundUpdate(\\n address indexed funder,\\n bytes32 indexed merkleRoot,\\n uint256 blockNr,\\n uint256 amount,\\n bool withdrawal\\n );\\n event MerkleClaim(address indexed claimer, address indexed rewardToken, uint256 indexed blockNr, uint256 amount);\\n\\n function rewardToken() external view returns (IERC20);\\n\\n function Rewards(\\n uint256 blockNumber\\n ) external view returns (uint256 balance, bytes32 merkleRoot, uint256 withdrawUnlockTime, uint256 ratio);\\n\\n function delegatorAddresses(address _delegator) external view returns (address originalRecipient);\\n\\n function setDelegator(address _recipient, address _delegator) external;\\n\\n function addReward(\\n uint256 amount,\\n bytes32 merkleRoot,\\n uint256 blockNumber,\\n uint256 withdrawUnlockTime,\\n uint256 totalStakedBalance\\n ) external;\\n\\n function withdrawFunds(uint256 blockNumber, uint256 amount) external;\\n\\n function claim(uint256 blockNumber, bytes[] calldata proof) external;\\n\\n function isClaimable(uint256 blockNumber, address account, bytes[] calldata proof) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xaa6ea729a26b7d515f1f4c9732a955d84253d5c57f68d40d0441f82c0955816a\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b506040516200320138038062003201833981016040819052620000349162000103565b60016000556200004433620000b1565b6001600160a01b0381166200009f5760405162461bcd60e51b815260206004820152601460248201527f546f6b656e2063616e6e6f74206265207a65726f000000000000000000000000604482015260640160405180910390fd5b6001600160a01b031660805262000135565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602082840312156200011657600080fd5b81516001600160a01b03811681146200012e57600080fd5b9392505050565b6080516130866200017b600039600081816101e1015281816104730152818161049d01528181610761015281816108650152818161090d0152610a5201526130866000f3fe608060405234801561001057600080fd5b50600436106100d35760003560e01c80639366452c11610081578063f301af421161005b578063f301af42146101bb578063f7c618c1146101dc578063f8738c251461020357600080fd5b80639366452c14610182578063e525310514610195578063f2fde38b146101a857600080fd5b80636d46379b116100b25780636d46379b14610146578063715018a6146101695780638da5cb5b1461017157600080fd5b8062501e28146100d85780631ce92be5146100ed57806341f891a414610100575b600080fd5b6100eb6100e6366004612c03565b61025a565b005b6100eb6100fb366004612c6b565b61051c565b61012961010e366004612c9e565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610159610154366004612cb9565b6105cd565b604051901515815260200161013d565b6100eb610667565b6001546001600160a01b0316610129565b6100eb610190366004612d13565b61067b565b6100eb6101a3366004612d4e565b61096e565b6100eb6101b6366004612c9e565b610ac9565b6101ce6101c9366004612d70565b610b59565b60405190815260200161013d565b6101297f000000000000000000000000000000000000000000000000000000000000000081565b61023a610211366004612d70565b600360208190526000918252604090912080546001820154600283015492909301549092919084565b60408051948552602085019390935291830152606082015260800161013d565b610262610b7a565b600083815260036020526040902060018101546102c65760405162461bcd60e51b815260206004820152601060248201527f526577617264206e6f7420666f756e640000000000000000000000000000000060448201526064015b60405180910390fd5b336000908152600460205260408120546001600160a01b03166102e95733610303565b336000908152600460205260409020546001600160a01b03165b604080516001600160a01b038316602082015260029181019190915290915060009060600160405160208183030381529060405280519060200120905060006103528460010154838888610bd3565b90506000670de0b6b3a764000085600301548361036f9190612d9f565b6103799190612dcc565b905080856000015410156103cf5760405162461bcd60e51b815260206004820152601d60248201527f436c61696d20756e6465722d66756e6465642062792066756e6465722e00000060448201526064016102bd565b600088815260036020908152604080832086845260040190915290205460ff161561043c5760405162461bcd60e51b815260206004820152600f60248201527f416c726561647920636c61696d6564000000000000000000000000000000000060448201526064016102bd565b60008381526004860160205260409020805460ff191660011790558454610464908290612de0565b855561049a6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168583610c70565b877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b03167fceea116ca90ae38b5f3bcd7482763d0bdd5915faed2146d37b1e3bcd1ea425378460405161050091815260200190565b60405180910390a450505050506105176001600055565b505050565b610524610d19565b6001600160a01b0382161580159061054457506001600160a01b03811615155b6105905760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420616464726573732070726f7669646564000000000000000060448201526064016102bd565b6001600160a01b03908116600090815260046020526040902080549190921673ffffffffffffffffffffffffffffffffffffffff19909116179055565b60008481526003602090815260408083206001015481516001600160a01b038816818501526002818401528251808203840181526060909101909252815191909201208183036106225760009250505061065f565b600087815260036020908152604080832084845260040190915290205460ff1615801561065a5750600061065883838888610bd3565b115b925050505b949350505050565b61066f610d19565b6106796000610d73565b565b610683610d19565b836106d05760405162461bcd60e51b815260206004820152601a60248201527f4d65726b6c6520726f6f742063616e6e6f74206265207a65726f00000000000060448201526064016102bd565b60008381526003602052604090206001810154156107305760405162461bcd60e51b815260206004820152601e60248201527f4d65726b6c6520726f6f742077617320616c726561647920706f73746564000060448201526064016102bd565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156107b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d49190612df3565b90506000871180156107e65750808711155b6108585760405162461bcd60e51b815260206004820152602660248201527f496e76616c696420616d6f756e74206f7220696e73756666696369656e74206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016102bd565b61088d6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308a610dd2565b8682556001820186905560028201849055826108b188670de0b6b3a7640000612d9f565b6108bb9190612dcc565b6003830155600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace01859055604080518881526020810187905290810185905286907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169033907f4993e379e2a0a87975314480436d8f2de32d291a64892cb63cdb0839d09044369060600160405180910390a450505050505050565b610976610d19565b600082815260036020526040902060028101544210156109d85760405162461bcd60e51b815260206004820152601c60248201527f52657761726473206d6179206e6f742062652077697468647261776e0000000060448201526064016102bd565b8054821115610a295760405162461bcd60e51b815260206004820152601460248201527f496e73756666696369656e742062616c616e636500000000000000000000000060448201526064016102bd565b81816000016000828254610a3d9190612de0565b9182905550825550610a796001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163384610c70565b6001808201546040805186815260208101869052908101929092529033907f210aece5a2bb3ac8bbec4d3bd83444123ef037a899b89d617e735799f983e6b39060600160405180910390a3505050565b610ad1610d19565b6001600160a01b038116610b4d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102bd565b610b5681610d73565b50565b60028181548110610b6957600080fd5b600091825260209091200154905081565b600260005403610bcc5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016102bd565b6002600055565b600080610c14610c0f86604051602001610bef91815260200190565b60408051601f19818403018152919052610c098688612e53565b89610e29565b610e4e565b905060005b8151811015610c6657818181518110610c3457610c34612f28565b016020015160f81c610c4884610100612d9f565b610c529190612f3e565b925080610c5e81612f51565b915050610c19565b5050949350505050565b6040516001600160a01b0383166024820152604481018290526105179084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610e67565b6001546001600160a01b031633146106795760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102bd565b600180546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6040516001600160a01b0380851660248301528316604482015260648101829052610e239085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610cb5565b50505050565b60606000610e3685610f4f565b9050610e43818585610f81565b9150505b9392505050565b6060610e61610e5c8361189d565b611959565b92915050565b6000610ebc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611a8e9092919063ffffffff16565b9050805160001480610edd575080806020019051810190610edd9190612f6a565b6105175760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016102bd565b60608180519060200120604051602001610f6b91815260200190565b6040516020818303038152906040529050919050565b60606000845111610fd45760405162461bcd60e51b815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b6579000000000000000000000060448201526064016102bd565b6000610fdf84611a9d565b90506000610fec86611b8c565b905060008460405160200161100391815260200190565b60405160208183030381529060405290506000805b845181101561182e57600085828151811061103557611035612f28565b6020026020010151905084518311156110b65760405162461bcd60e51b815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e67746800000000000000000000000000000000000060648201526084016102bd565b826000036111555780518051602091820120604051611104926110de92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b6111505760405162461bcd60e51b815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f74206861736800000060448201526064016102bd565b611278565b8051516020116111f1578051805160209182012060405161117f926110de92910190815260200190565b6111505760405162461bcd60e51b815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c20686173680000000000000000000000000000000000000000000000000060648201526084016102bd565b8051845160208087019190912082519190920120146112785760405162461bcd60e51b815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f652068617368000000000000000000000000000000000000000000000000000060648201526084016102bd565b61128460106001612f3e565b8160200151510361143157845183036113c95760006112c082602001516010815181106112b3576112b3612f28565b6020026020010151611959565b905060008151116113395760405162461bcd60e51b815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e636829000000000060648201526084016102bd565b600187516113479190612de0565b83146113bb5760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e63682900000000000060648201526084016102bd565b9650610e4795505050505050565b60008584815181106113dd576113dd612f28565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061140857611408612f28565b6020026020010151905061141b81611bef565b9550611428600186612f3e565b9450505061181b565b6002816020015151036117ad57600061144982611c14565b905060008160008151811061146057611460612f28565b016020015160f81c90506000611477600283612f8c565b611482906002612fae565b90506000611493848360ff16611c38565b905060006114a18a89611c38565b905060006114af8383611c6e565b9050808351146115275760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b657900000000000060648201526084016102bd565b60ff85166002148061153c575060ff85166003145b156116e257808251146115b75760405162461bcd60e51b815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e64657200000060648201526084016102bd565b60006115d388602001516001815181106112b3576112b3612f28565b9050600081511161164c5760405162461bcd60e51b815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c656166290000000000000060648201526084016102bd565b60018d5161165a9190612de0565b89146116ce5760405162461bcd60e51b815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c65616629000000000000000060648201526084016102bd565b9c50610e479b505050505050505050505050565b60ff851615806116f5575060ff85166001145b1561173457611721876020015160018151811061171457611714612f28565b6020026020010151611bef565b995061172d818a612f3e565b98506117a2565b60405162461bcd60e51b815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e20707265666978000000000000000000000000000060648201526084016102bd565b50505050505061181b565b60405162461bcd60e51b815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f646500000000000000000000000000000000000000000000000060648201526084016102bd565b508061182681612f51565b915050611018565b5060405162461bcd60e51b815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e747300000000000000000000000000000000000000000000000000000060648201526084016102bd565b6040805180820190915260008082526020820152600082511161193b5760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f206265606482015269206465636f6461626c6560b01b608482015260a4016102bd565b50604080518082019091528151815260209182019181019190915290565b6060600080600061196985611d05565b91945092509050600081600181111561198457611984612fc7565b146119f75760405162461bcd60e51b815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d0000000000000060648201526084016102bd565b611a018284612f3e565b855114611a765760405162461bcd60e51b815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e64657200000000000000000000000060648201526084016102bd565b611a85856020015184846125c7565b95945050505050565b606061065f8484600085612668565b805160609060008167ffffffffffffffff811115611abd57611abd612e0c565b604051908082528060200260200182016040528015611b0257816020015b6040805180820190915260608082526020820152815260200190600190039081611adb5790505b50905060005b82811015611b84576040518060400160405280868381518110611b2d57611b2d612f28565b60200260200101518152602001611b5c878481518110611b4f57611b4f612f28565b602002602001015161274f565b815250828281518110611b7157611b71612f28565b6020908102919091010152600101611b08565b509392505050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015611be4578060011b82018184015160001a8060041c8253600f811660018301535050600101611bb6565b509295945050505050565b60606020826000015110611c0b57611c0682611959565b610e61565b610e6182612762565b6060610e61611c3383602001516000815181106112b3576112b3612f28565b611b8c565b606082518210611c575750604080516020810190915260008152610e61565b610e478383848651611c699190612de0565b612778565b60008060008351855110611c83578351611c86565b84515b90505b8082108015611cf55750838281518110611ca557611ca5612f28565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858381518110611ce457611ce4612f28565b01602001516001600160f81b031916145b15611b8457816001019150611c89565b600080600080846000015111611d965760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f206265606482015269206465636f6461626c6560b01b608482015260a4016102bd565b6020840151805160001a607f8111611dbb5760006001600094509450945050506125c0565b60b78111611f65576000611dd0608083612de0565b905080876000015111611e715760405162461bcd60e51b815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a4016102bd565b6001838101516001600160f81b0319169082141580611eba57507f80000000000000000000000000000000000000000000000000000000000000006001600160f81b0319821610155b611f525760405162461bcd60e51b815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a4016102bd565b50600195509350600092506125c0915050565b60bf8111612233576000611f7a60b783612de0565b90508087600001511161201b5760405162461bcd60e51b815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a4016102bd565b60018301516001600160f81b03191660008190036120c75760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a4016102bd565b600184015160088302610100031c603781116121715760405162461bcd60e51b815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a4016102bd565b61217b8184612f3e565b8951116122165760405162461bcd60e51b815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a4016102bd565b612221836001612f3e565b97509550600094506125c09350505050565b60f781116122fa57600061224860c083612de0565b9050808760000151116122e95760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a4016102bd565b6001955093508492506125c0915050565b600061230760f783612de0565b9050808760000151116123a85760405162461bcd60e51b815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a4016102bd565b60018301516001600160f81b03191660008190036124545760405162461bcd60e51b815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a4016102bd565b600184015160088302610100031c603781116124fe5760405162461bcd60e51b815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a4016102bd565b6125088184612f3e565b8951116125a35760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a4016102bd565b6125ae836001612f3e565b97509550600194506125c09350505050565b9193909250565b606060008267ffffffffffffffff8111156125e4576125e4612e0c565b6040519080825280601f01601f19166020018201604052801561260e576020820181803683370190505b50905082600003612620579050610e47565b600061262c8587612f3e565b90506020820160005b8581101561264d578281015182820152602001612635565b8581111561265c576000868301525b50919695505050505050565b6060824710156126e05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016102bd565b600080866001600160a01b031685876040516126fc9190613001565b60006040518083038185875af1925050503d8060008114612739576040519150601f19603f3d011682016040523d82523d6000602084013e61273e565b606091505b509150915061065a878383876128e4565b6060610e6161275d8361189d565b61295d565b6060610e618260200151600084600001516125c7565b60608182601f0110156127cd5760405162461bcd60e51b815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016102bd565b82828401101561281f5760405162461bcd60e51b815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016102bd565b818301845110156128725760405162461bcd60e51b815260206004820152601160248201527f736c6963655f6f75744f66426f756e647300000000000000000000000000000060448201526064016102bd565b60608215801561289157604051915060008252602082016040526128db565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156128ca5780518352602092830192016128b2565b5050858452601f01601f1916604052505b50949350505050565b6060831561295357825160000361294c576001600160a01b0385163b61294c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102bd565b508161065f565b61065f8383612b8d565b6060600080600061296d85611d05565b91945092509050600181600181111561298857612988612fc7565b146129fb5760405162461bcd60e51b815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d000000000000000060648201526084016102bd565b8451612a078385612f3e565b14612a7a5760405162461bcd60e51b815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e646572000000000000000000000000000060648201526084016102bd565b6040805160208082526104208201909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081612a935790505090506000845b8751811015612b8157600080612b066040518060400160405280858d60000151612aea9190612de0565b8152602001858d60200151612aff9190612f3e565b9052611d05565b509150915060405180604001604052808383612b229190612f3e565b8152602001848c60200151612b379190612f3e565b815250858581518110612b4c57612b4c612f28565b6020908102919091010152612b62600185612f3e565b9350612b6e8183612f3e565b612b789084612f3e565b92505050612ac0565b50815295945050505050565b815115612b9d5781518083602001fd5b8060405162461bcd60e51b81526004016102bd919061301d565b60008083601f840112612bc957600080fd5b50813567ffffffffffffffff811115612be157600080fd5b6020830191508360208260051b8501011115612bfc57600080fd5b9250929050565b600080600060408486031215612c1857600080fd5b83359250602084013567ffffffffffffffff811115612c3657600080fd5b612c4286828701612bb7565b9497909650939450505050565b80356001600160a01b0381168114612c6657600080fd5b919050565b60008060408385031215612c7e57600080fd5b612c8783612c4f565b9150612c9560208401612c4f565b90509250929050565b600060208284031215612cb057600080fd5b610e4782612c4f565b60008060008060608587031215612ccf57600080fd5b84359350612cdf60208601612c4f565b9250604085013567ffffffffffffffff811115612cfb57600080fd5b612d0787828801612bb7565b95989497509550505050565b600080600080600060a08688031215612d2b57600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060408385031215612d6157600080fd5b50508035926020909101359150565b600060208284031215612d8257600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e6157610e61612d89565b634e487b7160e01b600052601260045260246000fd5b600082612ddb57612ddb612db6565b500490565b81810381811115610e6157610e61612d89565b600060208284031215612e0557600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612e4b57612e4b612e0c565b604052919050565b600067ffffffffffffffff80841115612e6e57612e6e612e0c565b8360051b6020612e7f818301612e22565b868152918501918181019036841115612e9757600080fd5b865b84811015612f1c57803586811115612eb15760008081fd5b8801601f3681830112612ec45760008081fd5b813588811115612ed657612ed6612e0c565b612ee7818301601f19168801612e22565b91508082523687828501011115612efe5760008081fd5b80878401888401376000908201870152845250918301918301612e99565b50979650505050505050565b634e487b7160e01b600052603260045260246000fd5b80820180821115610e6157610e61612d89565b600060018201612f6357612f63612d89565b5060010190565b600060208284031215612f7c57600080fd5b81518015158114610e4757600080fd5b600060ff831680612f9f57612f9f612db6565b8060ff84160691505092915050565b60ff8281168282160390811115610e6157610e61612d89565b634e487b7160e01b600052602160045260246000fd5b60005b83811015612ff8578181015183820152602001612fe0565b50506000910152565b60008251613013818460208701612fdd565b9190910192915050565b602081526000825180602084015261303c816040850160208701612fdd565b601f01601f1916919091016040019291505056fea2646970667358221220ef586eb6a714f1d80c54375ad6c7029882b499d015fab7a74b47a02e7dd863e864736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d35760003560e01c80639366452c11610081578063f301af421161005b578063f301af42146101bb578063f7c618c1146101dc578063f8738c251461020357600080fd5b80639366452c14610182578063e525310514610195578063f2fde38b146101a857600080fd5b80636d46379b116100b25780636d46379b14610146578063715018a6146101695780638da5cb5b1461017157600080fd5b8062501e28146100d85780631ce92be5146100ed57806341f891a414610100575b600080fd5b6100eb6100e6366004612c03565b61025a565b005b6100eb6100fb366004612c6b565b61051c565b61012961010e366004612c9e565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610159610154366004612cb9565b6105cd565b604051901515815260200161013d565b6100eb610667565b6001546001600160a01b0316610129565b6100eb610190366004612d13565b61067b565b6100eb6101a3366004612d4e565b61096e565b6100eb6101b6366004612c9e565b610ac9565b6101ce6101c9366004612d70565b610b59565b60405190815260200161013d565b6101297f000000000000000000000000000000000000000000000000000000000000000081565b61023a610211366004612d70565b600360208190526000918252604090912080546001820154600283015492909301549092919084565b60408051948552602085019390935291830152606082015260800161013d565b610262610b7a565b600083815260036020526040902060018101546102c65760405162461bcd60e51b815260206004820152601060248201527f526577617264206e6f7420666f756e640000000000000000000000000000000060448201526064015b60405180910390fd5b336000908152600460205260408120546001600160a01b03166102e95733610303565b336000908152600460205260409020546001600160a01b03165b604080516001600160a01b038316602082015260029181019190915290915060009060600160405160208183030381529060405280519060200120905060006103528460010154838888610bd3565b90506000670de0b6b3a764000085600301548361036f9190612d9f565b6103799190612dcc565b905080856000015410156103cf5760405162461bcd60e51b815260206004820152601d60248201527f436c61696d20756e6465722d66756e6465642062792066756e6465722e00000060448201526064016102bd565b600088815260036020908152604080832086845260040190915290205460ff161561043c5760405162461bcd60e51b815260206004820152600f60248201527f416c726561647920636c61696d6564000000000000000000000000000000000060448201526064016102bd565b60008381526004860160205260409020805460ff191660011790558454610464908290612de0565b855561049a6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168583610c70565b877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b03167fceea116ca90ae38b5f3bcd7482763d0bdd5915faed2146d37b1e3bcd1ea425378460405161050091815260200190565b60405180910390a450505050506105176001600055565b505050565b610524610d19565b6001600160a01b0382161580159061054457506001600160a01b03811615155b6105905760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420616464726573732070726f7669646564000000000000000060448201526064016102bd565b6001600160a01b03908116600090815260046020526040902080549190921673ffffffffffffffffffffffffffffffffffffffff19909116179055565b60008481526003602090815260408083206001015481516001600160a01b038816818501526002818401528251808203840181526060909101909252815191909201208183036106225760009250505061065f565b600087815260036020908152604080832084845260040190915290205460ff1615801561065a5750600061065883838888610bd3565b115b925050505b949350505050565b61066f610d19565b6106796000610d73565b565b610683610d19565b836106d05760405162461bcd60e51b815260206004820152601a60248201527f4d65726b6c6520726f6f742063616e6e6f74206265207a65726f00000000000060448201526064016102bd565b60008381526003602052604090206001810154156107305760405162461bcd60e51b815260206004820152601e60248201527f4d65726b6c6520726f6f742077617320616c726561647920706f73746564000060448201526064016102bd565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156107b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d49190612df3565b90506000871180156107e65750808711155b6108585760405162461bcd60e51b815260206004820152602660248201527f496e76616c696420616d6f756e74206f7220696e73756666696369656e74206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016102bd565b61088d6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308a610dd2565b8682556001820186905560028201849055826108b188670de0b6b3a7640000612d9f565b6108bb9190612dcc565b6003830155600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace01859055604080518881526020810187905290810185905286907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169033907f4993e379e2a0a87975314480436d8f2de32d291a64892cb63cdb0839d09044369060600160405180910390a450505050505050565b610976610d19565b600082815260036020526040902060028101544210156109d85760405162461bcd60e51b815260206004820152601c60248201527f52657761726473206d6179206e6f742062652077697468647261776e0000000060448201526064016102bd565b8054821115610a295760405162461bcd60e51b815260206004820152601460248201527f496e73756666696369656e742062616c616e636500000000000000000000000060448201526064016102bd565b81816000016000828254610a3d9190612de0565b9182905550825550610a796001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163384610c70565b6001808201546040805186815260208101869052908101929092529033907f210aece5a2bb3ac8bbec4d3bd83444123ef037a899b89d617e735799f983e6b39060600160405180910390a3505050565b610ad1610d19565b6001600160a01b038116610b4d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102bd565b610b5681610d73565b50565b60028181548110610b6957600080fd5b600091825260209091200154905081565b600260005403610bcc5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016102bd565b6002600055565b600080610c14610c0f86604051602001610bef91815260200190565b60408051601f19818403018152919052610c098688612e53565b89610e29565b610e4e565b905060005b8151811015610c6657818181518110610c3457610c34612f28565b016020015160f81c610c4884610100612d9f565b610c529190612f3e565b925080610c5e81612f51565b915050610c19565b5050949350505050565b6040516001600160a01b0383166024820152604481018290526105179084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610e67565b6001546001600160a01b031633146106795760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102bd565b600180546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6040516001600160a01b0380851660248301528316604482015260648101829052610e239085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610cb5565b50505050565b60606000610e3685610f4f565b9050610e43818585610f81565b9150505b9392505050565b6060610e61610e5c8361189d565b611959565b92915050565b6000610ebc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611a8e9092919063ffffffff16565b9050805160001480610edd575080806020019051810190610edd9190612f6a565b6105175760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016102bd565b60608180519060200120604051602001610f6b91815260200190565b6040516020818303038152906040529050919050565b60606000845111610fd45760405162461bcd60e51b815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b6579000000000000000000000060448201526064016102bd565b6000610fdf84611a9d565b90506000610fec86611b8c565b905060008460405160200161100391815260200190565b60405160208183030381529060405290506000805b845181101561182e57600085828151811061103557611035612f28565b6020026020010151905084518311156110b65760405162461bcd60e51b815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e67746800000000000000000000000000000000000060648201526084016102bd565b826000036111555780518051602091820120604051611104926110de92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b6111505760405162461bcd60e51b815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f74206861736800000060448201526064016102bd565b611278565b8051516020116111f1578051805160209182012060405161117f926110de92910190815260200190565b6111505760405162461bcd60e51b815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c20686173680000000000000000000000000000000000000000000000000060648201526084016102bd565b8051845160208087019190912082519190920120146112785760405162461bcd60e51b815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f652068617368000000000000000000000000000000000000000000000000000060648201526084016102bd565b61128460106001612f3e565b8160200151510361143157845183036113c95760006112c082602001516010815181106112b3576112b3612f28565b6020026020010151611959565b905060008151116113395760405162461bcd60e51b815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e636829000000000060648201526084016102bd565b600187516113479190612de0565b83146113bb5760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e63682900000000000060648201526084016102bd565b9650610e4795505050505050565b60008584815181106113dd576113dd612f28565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061140857611408612f28565b6020026020010151905061141b81611bef565b9550611428600186612f3e565b9450505061181b565b6002816020015151036117ad57600061144982611c14565b905060008160008151811061146057611460612f28565b016020015160f81c90506000611477600283612f8c565b611482906002612fae565b90506000611493848360ff16611c38565b905060006114a18a89611c38565b905060006114af8383611c6e565b9050808351146115275760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b657900000000000060648201526084016102bd565b60ff85166002148061153c575060ff85166003145b156116e257808251146115b75760405162461bcd60e51b815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e64657200000060648201526084016102bd565b60006115d388602001516001815181106112b3576112b3612f28565b9050600081511161164c5760405162461bcd60e51b815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c656166290000000000000060648201526084016102bd565b60018d5161165a9190612de0565b89146116ce5760405162461bcd60e51b815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c65616629000000000000000060648201526084016102bd565b9c50610e479b505050505050505050505050565b60ff851615806116f5575060ff85166001145b1561173457611721876020015160018151811061171457611714612f28565b6020026020010151611bef565b995061172d818a612f3e565b98506117a2565b60405162461bcd60e51b815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e20707265666978000000000000000000000000000060648201526084016102bd565b50505050505061181b565b60405162461bcd60e51b815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f646500000000000000000000000000000000000000000000000060648201526084016102bd565b508061182681612f51565b915050611018565b5060405162461bcd60e51b815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e747300000000000000000000000000000000000000000000000000000060648201526084016102bd565b6040805180820190915260008082526020820152600082511161193b5760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f206265606482015269206465636f6461626c6560b01b608482015260a4016102bd565b50604080518082019091528151815260209182019181019190915290565b6060600080600061196985611d05565b91945092509050600081600181111561198457611984612fc7565b146119f75760405162461bcd60e51b815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d0000000000000060648201526084016102bd565b611a018284612f3e565b855114611a765760405162461bcd60e51b815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e64657200000000000000000000000060648201526084016102bd565b611a85856020015184846125c7565b95945050505050565b606061065f8484600085612668565b805160609060008167ffffffffffffffff811115611abd57611abd612e0c565b604051908082528060200260200182016040528015611b0257816020015b6040805180820190915260608082526020820152815260200190600190039081611adb5790505b50905060005b82811015611b84576040518060400160405280868381518110611b2d57611b2d612f28565b60200260200101518152602001611b5c878481518110611b4f57611b4f612f28565b602002602001015161274f565b815250828281518110611b7157611b71612f28565b6020908102919091010152600101611b08565b509392505050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015611be4578060011b82018184015160001a8060041c8253600f811660018301535050600101611bb6565b509295945050505050565b60606020826000015110611c0b57611c0682611959565b610e61565b610e6182612762565b6060610e61611c3383602001516000815181106112b3576112b3612f28565b611b8c565b606082518210611c575750604080516020810190915260008152610e61565b610e478383848651611c699190612de0565b612778565b60008060008351855110611c83578351611c86565b84515b90505b8082108015611cf55750838281518110611ca557611ca5612f28565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858381518110611ce457611ce4612f28565b01602001516001600160f81b031916145b15611b8457816001019150611c89565b600080600080846000015111611d965760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f206265606482015269206465636f6461626c6560b01b608482015260a4016102bd565b6020840151805160001a607f8111611dbb5760006001600094509450945050506125c0565b60b78111611f65576000611dd0608083612de0565b905080876000015111611e715760405162461bcd60e51b815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a4016102bd565b6001838101516001600160f81b0319169082141580611eba57507f80000000000000000000000000000000000000000000000000000000000000006001600160f81b0319821610155b611f525760405162461bcd60e51b815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a4016102bd565b50600195509350600092506125c0915050565b60bf8111612233576000611f7a60b783612de0565b90508087600001511161201b5760405162461bcd60e51b815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a4016102bd565b60018301516001600160f81b03191660008190036120c75760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a4016102bd565b600184015160088302610100031c603781116121715760405162461bcd60e51b815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a4016102bd565b61217b8184612f3e565b8951116122165760405162461bcd60e51b815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a4016102bd565b612221836001612f3e565b97509550600094506125c09350505050565b60f781116122fa57600061224860c083612de0565b9050808760000151116122e95760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a4016102bd565b6001955093508492506125c0915050565b600061230760f783612de0565b9050808760000151116123a85760405162461bcd60e51b815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a4016102bd565b60018301516001600160f81b03191660008190036124545760405162461bcd60e51b815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a4016102bd565b600184015160088302610100031c603781116124fe5760405162461bcd60e51b815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a4016102bd565b6125088184612f3e565b8951116125a35760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a4016102bd565b6125ae836001612f3e565b97509550600194506125c09350505050565b9193909250565b606060008267ffffffffffffffff8111156125e4576125e4612e0c565b6040519080825280601f01601f19166020018201604052801561260e576020820181803683370190505b50905082600003612620579050610e47565b600061262c8587612f3e565b90506020820160005b8581101561264d578281015182820152602001612635565b8581111561265c576000868301525b50919695505050505050565b6060824710156126e05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016102bd565b600080866001600160a01b031685876040516126fc9190613001565b60006040518083038185875af1925050503d8060008114612739576040519150601f19603f3d011682016040523d82523d6000602084013e61273e565b606091505b509150915061065a878383876128e4565b6060610e6161275d8361189d565b61295d565b6060610e618260200151600084600001516125c7565b60608182601f0110156127cd5760405162461bcd60e51b815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016102bd565b82828401101561281f5760405162461bcd60e51b815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016102bd565b818301845110156128725760405162461bcd60e51b815260206004820152601160248201527f736c6963655f6f75744f66426f756e647300000000000000000000000000000060448201526064016102bd565b60608215801561289157604051915060008252602082016040526128db565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156128ca5780518352602092830192016128b2565b5050858452601f01601f1916604052505b50949350505050565b6060831561295357825160000361294c576001600160a01b0385163b61294c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102bd565b508161065f565b61065f8383612b8d565b6060600080600061296d85611d05565b91945092509050600181600181111561298857612988612fc7565b146129fb5760405162461bcd60e51b815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d000000000000000060648201526084016102bd565b8451612a078385612f3e565b14612a7a5760405162461bcd60e51b815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e646572000000000000000000000000000060648201526084016102bd565b6040805160208082526104208201909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081612a935790505090506000845b8751811015612b8157600080612b066040518060400160405280858d60000151612aea9190612de0565b8152602001858d60200151612aff9190612f3e565b9052611d05565b509150915060405180604001604052808383612b229190612f3e565b8152602001848c60200151612b379190612f3e565b815250858581518110612b4c57612b4c612f28565b6020908102919091010152612b62600185612f3e565b9350612b6e8183612f3e565b612b789084612f3e565b92505050612ac0565b50815295945050505050565b815115612b9d5781518083602001fd5b8060405162461bcd60e51b81526004016102bd919061301d565b60008083601f840112612bc957600080fd5b50813567ffffffffffffffff811115612be157600080fd5b6020830191508360208260051b8501011115612bfc57600080fd5b9250929050565b600080600060408486031215612c1857600080fd5b83359250602084013567ffffffffffffffff811115612c3657600080fd5b612c4286828701612bb7565b9497909650939450505050565b80356001600160a01b0381168114612c6657600080fd5b919050565b60008060408385031215612c7e57600080fd5b612c8783612c4f565b9150612c9560208401612c4f565b90509250929050565b600060208284031215612cb057600080fd5b610e4782612c4f565b60008060008060608587031215612ccf57600080fd5b84359350612cdf60208601612c4f565b9250604085013567ffffffffffffffff811115612cfb57600080fd5b612d0787828801612bb7565b95989497509550505050565b600080600080600060a08688031215612d2b57600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060408385031215612d6157600080fd5b50508035926020909101359150565b600060208284031215612d8257600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e6157610e61612d89565b634e487b7160e01b600052601260045260246000fd5b600082612ddb57612ddb612db6565b500490565b81810381811115610e6157610e61612d89565b600060208284031215612e0557600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612e4b57612e4b612e0c565b604052919050565b600067ffffffffffffffff80841115612e6e57612e6e612e0c565b8360051b6020612e7f818301612e22565b868152918501918181019036841115612e9757600080fd5b865b84811015612f1c57803586811115612eb15760008081fd5b8801601f3681830112612ec45760008081fd5b813588811115612ed657612ed6612e0c565b612ee7818301601f19168801612e22565b91508082523687828501011115612efe5760008081fd5b80878401888401376000908201870152845250918301918301612e99565b50979650505050505050565b634e487b7160e01b600052603260045260246000fd5b80820180821115610e6157610e61612d89565b600060018201612f6357612f63612d89565b5060010190565b600060208284031215612f7c57600080fd5b81518015158114610e4757600080fd5b600060ff831680612f9f57612f9f612db6565b8060ff84160691505092915050565b60ff8281168282160390811115610e6157610e61612d89565b634e487b7160e01b600052602160045260246000fd5b60005b83811015612ff8578181015183820152602001612fe0565b50506000910152565b60008251613013818460208701612fdd565b9190910192915050565b602081526000825180602084015261303c816040850160208701612fdd565b601f01601f1916919091016040019291505056fea2646970667358221220ef586eb6a714f1d80c54375ad6c7029882b499d015fab7a74b47a02e7dd863e864736f6c63430008130033", + "devdoc": { + "kind": "dev", + "methods": { + "addReward(uint256,bytes32,uint256,uint256,uint256)": { + "params": { + "amount": "The amount of reward tokens to deposit", + "blockNumber": "The block number for the Reward", + "merkleRoot": "The merkle root of the distribution tree", + "totalStakedBalance": "Total staked balance of the merkleRoot (computed off-chain)", + "withdrawUnlockTime": "The timestamp after which withdrawals by owner are allowed" + } + }, + "claim(uint256,bytes[])": { + "details": "Checks proofs and claims tracking before transferring rewardTokens", + "params": { + "blockNumber": "The block number for the Reward", + "proof": "The merkle proof for the claim" + } + }, + "constructor": { + "params": { + "_rewardToken": "The reward token to be distributed" + } + }, + "isClaimable(uint256,address,bytes[])": { + "params": { + "account": "The address of the account claiming", + "blockNumber": "The block number for the Reward", + "proof": "The merkle proof for the claim" + }, + "returns": { + "_0": "A bool indicating if the claim is valid and claimable" + } + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "setDelegator(address,address)": { + "params": { + "_delegator": "The address that sould claim on behalf of the owner", + "_recipient": "original eligible recipient address" + } + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + }, + "withdrawFunds(uint256,uint256)": { + "params": { + "amount": "The amount to withdraw", + "blockNumber": "The block number for the Reward" + } + } + }, + "title": "Sonne Finance Merkle tree-based rewards distributor", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "addReward(uint256,bytes32,uint256,uint256,uint256)": { + "notice": "Creates a new Reward struct for a rewards distribution" + }, + "claim(uint256,bytes[])": { + "notice": "Claims the specified amount for an account if valid" + }, + "constructor": { + "notice": "Contract constructor to initialize rewardToken" + }, + "isClaimable(uint256,address,bytes[])": { + "notice": "Checks if a claim is valid and claimable" + }, + "setDelegator(address,address)": { + "notice": "Sets a delegator address for a given recipient" + }, + "withdrawFunds(uint256,uint256)": { + "notice": "Allows to withdraw available funds to owner after unlock time" + } + }, + "notice": "Contract to distribute rewards on BASE network to Sonne Finance Optimism stakers", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 1420, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "_status", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 1304, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "_owner", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 3325, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "rewards", + "offset": 0, + "slot": "2", + "type": "t_array(t_uint256)dyn_storage" + }, + { + "astId": 3330, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "Rewards", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Reward)3319_storage)" + }, + { + "astId": 3334, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "delegatorAddresses", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_address,t_address)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)dyn_storage": { + "base": "t_uint256", + "encoding": "dynamic_array", + "label": "uint256[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_address)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_bytes32,t_bool)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_uint256,t_struct(Reward)3319_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct SonneMerkleDistributor.Reward)", + "numberOfBytes": "32", + "value": "t_struct(Reward)3319_storage" + }, + "t_struct(Reward)3319_storage": { + "encoding": "inplace", + "label": "struct SonneMerkleDistributor.Reward", + "members": [ + { + "astId": 3308, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "balance", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 3310, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "merkleRoot", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + }, + { + "astId": 3312, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "withdrawUnlockTime", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 3314, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "ratio", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 3318, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "leafClaimed", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_bytes32,t_bool)" + } + ], + "numberOfBytes": "160" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/crosschain-rewards/deployments/base/UsdcMerkleDistributor.json b/crosschain-rewards/deployments/base/UsdcMerkleDistributor.json new file mode 100644 index 0000000..ac7a20c --- /dev/null +++ b/crosschain-rewards/deployments/base/UsdcMerkleDistributor.json @@ -0,0 +1,643 @@ +{ + "address": "0x2bcA56E08c854a6922B653A18D46f216Ed4aa326", + "abi": [ + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_rewardToken", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "claimer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "blockNr", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "MerkleClaim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "funder", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "merkleRoot", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "blockNr", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "withdrawal", + "type": "bool" + } + ], + "name": "MerkleFundUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "merkleRoot", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "blockNr", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "withdrawUnlockTime", + "type": "uint256" + } + ], + "name": "NewMerkle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "Rewards", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "merkleRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "withdrawUnlockTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ratio", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "merkleRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "withdrawUnlockTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalStakedBalance", + "type": "uint256" + } + ], + "name": "addReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "bytes[]", + "name": "proof", + "type": "bytes[]" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "delegatorAddresses", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes[]", + "name": "proof", + "type": "bytes[]" + } + ], + "name": "isClaimable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "address", + "name": "_delegator", + "type": "address" + } + ], + "name": "setDelegator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x996b50a8b250803dfa491f394721151f44a75f09a285e2873ce807b61717fd8b", + "receipt": { + "to": null, + "from": "0xFb59Ce8986943163F14C590755b29dB2998F2322", + "contractAddress": "0x2bcA56E08c854a6922B653A18D46f216Ed4aa326", + "transactionIndex": 4, + "gasUsed": "2776101", + "logsBloom": "0x00000000000000000000000000000000000000100000000000804000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000020000000000000800000000000000000000000000000000400000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000004000000000000000000000000000", + "blockHash": "0xb56a3935521c2ce5e45a5d915034dbd11645eeae2f9ca9e43ebf63b52908059d", + "transactionHash": "0x996b50a8b250803dfa491f394721151f44a75f09a285e2873ce807b61717fd8b", + "logs": [ + { + "transactionIndex": 4, + "blockNumber": 4220274, + "transactionHash": "0x996b50a8b250803dfa491f394721151f44a75f09a285e2873ce807b61717fd8b", + "address": "0x2bcA56E08c854a6922B653A18D46f216Ed4aa326", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000fb59ce8986943163f14c590755b29db2998f2322" + ], + "data": "0x", + "logIndex": 9, + "blockHash": "0xb56a3935521c2ce5e45a5d915034dbd11645eeae2f9ca9e43ebf63b52908059d" + } + ], + "blockNumber": 4220274, + "cumulativeGasUsed": "3260907", + "status": 1, + "byzantium": true + }, + "args": [ + "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" + ], + "numDeployments": 1, + "solcInputHash": "30087f7fee47449a419e52a71b53a636", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"_rewardToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"claimer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNr\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"MerkleClaim\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"funder\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNr\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"withdrawal\",\"type\":\"bool\"}],\"name\":\"MerkleFundUpdate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNr\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"withdrawUnlockTime\",\"type\":\"uint256\"}],\"name\":\"NewMerkle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"Rewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"withdrawUnlockTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ratio\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"withdrawUnlockTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalStakedBalance\",\"type\":\"uint256\"}],\"name\":\"addReward\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"proof\",\"type\":\"bytes[]\"}],\"name\":\"claim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"delegatorAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes[]\",\"name\":\"proof\",\"type\":\"bytes[]\"}],\"name\":\"isClaimable\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardToken\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"rewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_delegator\",\"type\":\"address\"}],\"name\":\"setDelegator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addReward(uint256,bytes32,uint256,uint256,uint256)\":{\"params\":{\"amount\":\"The amount of reward tokens to deposit\",\"blockNumber\":\"The block number for the Reward\",\"merkleRoot\":\"The merkle root of the distribution tree\",\"totalStakedBalance\":\"Total staked balance of the merkleRoot (computed off-chain)\",\"withdrawUnlockTime\":\"The timestamp after which withdrawals by owner are allowed\"}},\"claim(uint256,bytes[])\":{\"details\":\"Checks proofs and claims tracking before transferring rewardTokens\",\"params\":{\"blockNumber\":\"The block number for the Reward\",\"proof\":\"The merkle proof for the claim\"}},\"constructor\":{\"params\":{\"_rewardToken\":\"The reward token to be distributed\"}},\"isClaimable(uint256,address,bytes[])\":{\"params\":{\"account\":\"The address of the account claiming\",\"blockNumber\":\"The block number for the Reward\",\"proof\":\"The merkle proof for the claim\"},\"returns\":{\"_0\":\"A bool indicating if the claim is valid and claimable\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setDelegator(address,address)\":{\"params\":{\"_delegator\":\"The address that sould claim on behalf of the owner\",\"_recipient\":\"original eligible recipient address\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"withdrawFunds(uint256,uint256)\":{\"params\":{\"amount\":\"The amount to withdraw\",\"blockNumber\":\"The block number for the Reward\"}}},\"title\":\"Sonne Finance Merkle tree-based rewards distributor\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addReward(uint256,bytes32,uint256,uint256,uint256)\":{\"notice\":\"Creates a new Reward struct for a rewards distribution\"},\"claim(uint256,bytes[])\":{\"notice\":\"Claims the specified amount for an account if valid\"},\"constructor\":{\"notice\":\"Contract constructor to initialize rewardToken\"},\"isClaimable(uint256,address,bytes[])\":{\"notice\":\"Checks if a claim is valid and claimable\"},\"setDelegator(address,address)\":{\"notice\":\"Sets a delegator address for a given recipient\"},\"withdrawFunds(uint256,uint256)\":{\"notice\":\"Allows to withdraw available funds to owner after unlock time\"}},\"notice\":\"Contract to distribute rewards on BASE network to Sonne Finance Optimism stakers\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/SonneMerkleDistributor.sol\":\"SonneMerkleDistributor\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/libraries/Bytes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title Bytes\\n/// @notice Bytes is a library for manipulating byte arrays.\\nlibrary Bytes {\\n /// @custom:attribution https://github.com/GNSPS/solidity-bytes-utils\\n /// @notice Slices a byte array with a given starting index and length. Returns a new byte array\\n /// as opposed to a pointer to the original array. Will throw if trying to slice more\\n /// bytes than exist in the array.\\n /// @param _bytes Byte array to slice.\\n /// @param _start Starting index of the slice.\\n /// @param _length Length of the slice.\\n /// @return Slice of the input byte array.\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n ) internal pure returns (bytes memory) {\\n unchecked {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_start + _length >= _start, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n }\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n /// @notice Slices a byte array with a given starting index up to the end of the original byte\\n /// array. Returns a new array rathern than a pointer to the original.\\n /// @param _bytes Byte array to slice.\\n /// @param _start Starting index of the slice.\\n /// @return Slice of the input byte array.\\n function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) {\\n if (_start >= _bytes.length) {\\n return bytes(\\\"\\\");\\n }\\n return slice(_bytes, _start, _bytes.length - _start);\\n }\\n\\n /// @notice Converts a byte array into a nibble array by splitting each byte into two nibbles.\\n /// Resulting nibble array will be exactly twice as long as the input byte array.\\n /// @param _bytes Input byte array to convert.\\n /// @return Resulting nibble array.\\n function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) {\\n bytes memory _nibbles;\\n assembly {\\n // Grab a free memory offset for the new array\\n _nibbles := mload(0x40)\\n\\n // Load the length of the passed bytes array from memory\\n let bytesLength := mload(_bytes)\\n\\n // Calculate the length of the new nibble array\\n // This is the length of the input array times 2\\n let nibblesLength := shl(0x01, bytesLength)\\n\\n // Update the free memory pointer to allocate memory for the new array.\\n // To do this, we add the length of the new array + 32 bytes for the array length\\n // rounded up to the nearest 32 byte boundary to the current free memory pointer.\\n mstore(0x40, add(_nibbles, and(not(0x1F), add(nibblesLength, 0x3F))))\\n\\n // Store the length of the new array in memory\\n mstore(_nibbles, nibblesLength)\\n\\n // Store the memory offset of the _bytes array's contents on the stack\\n let bytesStart := add(_bytes, 0x20)\\n\\n // Store the memory offset of the nibbles array's contents on the stack\\n let nibblesStart := add(_nibbles, 0x20)\\n\\n // Loop through each byte in the input array\\n for {\\n let i := 0x00\\n } lt(i, bytesLength) {\\n i := add(i, 0x01)\\n } {\\n // Get the starting offset of the next 2 bytes in the nibbles array\\n let offset := add(nibblesStart, shl(0x01, i))\\n // Load the byte at the current index within the `_bytes` array\\n let b := byte(0x00, mload(add(bytesStart, i)))\\n\\n // Pull out the first nibble and store it in the new array\\n mstore8(offset, shr(0x04, b))\\n // Pull out the second nibble and store it in the new array\\n mstore8(add(offset, 0x01), and(b, 0x0F))\\n }\\n }\\n return _nibbles;\\n }\\n\\n /// @notice Compares two byte arrays by comparing their keccak256 hashes.\\n /// @param _bytes First byte array to compare.\\n /// @param _other Second byte array to compare.\\n /// @return True if the two byte arrays are equal, false otherwise.\\n function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) {\\n return keccak256(_bytes) == keccak256(_other);\\n }\\n}\\n\",\"keccak256\":\"0x6fa7ba368cfee95b16b177c92745583736ad623befb81c8ae98ce020e670ce44\",\"license\":\"MIT\"},\"@eth-optimism/contracts-bedrock/contracts/libraries/rlp/RLPReader.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.8;\\n\\n/**\\n * @custom:attribution https://github.com/hamdiallam/Solidity-RLP\\n * @title RLPReader\\n * @notice RLPReader is a library for parsing RLP-encoded byte arrays into Solidity types. Adapted\\n * from Solidity-RLP (https://github.com/hamdiallam/Solidity-RLP) by Hamdi Allam with\\n * various tweaks to improve readability.\\n */\\nlibrary RLPReader {\\n /**\\n * Custom pointer type to avoid confusion between pointers and uint256s.\\n */\\n type MemoryPointer is uint256;\\n\\n /**\\n * @notice RLP item types.\\n *\\n * @custom:value DATA_ITEM Represents an RLP data item (NOT a list).\\n * @custom:value LIST_ITEM Represents an RLP list item.\\n */\\n enum RLPItemType {\\n DATA_ITEM,\\n LIST_ITEM\\n }\\n\\n /**\\n * @notice Struct representing an RLP item.\\n *\\n * @custom:field length Length of the RLP item.\\n * @custom:field ptr Pointer to the RLP item in memory.\\n */\\n struct RLPItem {\\n uint256 length;\\n MemoryPointer ptr;\\n }\\n\\n /**\\n * @notice Max list length that this library will accept.\\n */\\n uint256 internal constant MAX_LIST_LENGTH = 32;\\n\\n /**\\n * @notice Converts bytes to a reference to memory position and length.\\n *\\n * @param _in Input bytes to convert.\\n *\\n * @return Output memory reference.\\n */\\n function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory) {\\n // Empty arrays are not RLP items.\\n require(\\n _in.length > 0,\\n \\\"RLPReader: length of an RLP item must be greater than zero to be decodable\\\"\\n );\\n\\n MemoryPointer ptr;\\n assembly {\\n ptr := add(_in, 32)\\n }\\n\\n return RLPItem({ length: _in.length, ptr: ptr });\\n }\\n\\n /**\\n * @notice Reads an RLP list value into a list of RLP items.\\n *\\n * @param _in RLP list value.\\n *\\n * @return Decoded RLP list items.\\n */\\n function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) {\\n (uint256 listOffset, uint256 listLength, RLPItemType itemType) = _decodeLength(_in);\\n\\n require(\\n itemType == RLPItemType.LIST_ITEM,\\n \\\"RLPReader: decoded item type for list is not a list item\\\"\\n );\\n\\n require(\\n listOffset + listLength == _in.length,\\n \\\"RLPReader: list item has an invalid data remainder\\\"\\n );\\n\\n // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by\\n // writing to the length. Since we can't know the number of RLP items without looping over\\n // the entire input, we'd have to loop twice to accurately size this array. It's easier to\\n // simply set a reasonable maximum list length and decrease the size before we finish.\\n RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH);\\n\\n uint256 itemCount = 0;\\n uint256 offset = listOffset;\\n while (offset < _in.length) {\\n (uint256 itemOffset, uint256 itemLength, ) = _decodeLength(\\n RLPItem({\\n length: _in.length - offset,\\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\\n })\\n );\\n\\n // We don't need to check itemCount < out.length explicitly because Solidity already\\n // handles this check on our behalf, we'd just be wasting gas.\\n out[itemCount] = RLPItem({\\n length: itemLength + itemOffset,\\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\\n });\\n\\n itemCount += 1;\\n offset += itemOffset + itemLength;\\n }\\n\\n // Decrease the array size to match the actual item count.\\n assembly {\\n mstore(out, itemCount)\\n }\\n\\n return out;\\n }\\n\\n /**\\n * @notice Reads an RLP list value into a list of RLP items.\\n *\\n * @param _in RLP list value.\\n *\\n * @return Decoded RLP list items.\\n */\\n function readList(bytes memory _in) internal pure returns (RLPItem[] memory) {\\n return readList(toRLPItem(_in));\\n }\\n\\n /**\\n * @notice Reads an RLP bytes value into bytes.\\n *\\n * @param _in RLP bytes value.\\n *\\n * @return Decoded bytes.\\n */\\n function readBytes(RLPItem memory _in) internal pure returns (bytes memory) {\\n (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);\\n\\n require(\\n itemType == RLPItemType.DATA_ITEM,\\n \\\"RLPReader: decoded item type for bytes is not a data item\\\"\\n );\\n\\n require(\\n _in.length == itemOffset + itemLength,\\n \\\"RLPReader: bytes value contains an invalid remainder\\\"\\n );\\n\\n return _copy(_in.ptr, itemOffset, itemLength);\\n }\\n\\n /**\\n * @notice Reads an RLP bytes value into bytes.\\n *\\n * @param _in RLP bytes value.\\n *\\n * @return Decoded bytes.\\n */\\n function readBytes(bytes memory _in) internal pure returns (bytes memory) {\\n return readBytes(toRLPItem(_in));\\n }\\n\\n /**\\n * @notice Reads the raw bytes of an RLP item.\\n *\\n * @param _in RLP item to read.\\n *\\n * @return Raw RLP bytes.\\n */\\n function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory) {\\n return _copy(_in.ptr, 0, _in.length);\\n }\\n\\n /**\\n * @notice Decodes the length of an RLP item.\\n *\\n * @param _in RLP item to decode.\\n *\\n * @return Offset of the encoded data.\\n * @return Length of the encoded data.\\n * @return RLP item type (LIST_ITEM or DATA_ITEM).\\n */\\n function _decodeLength(RLPItem memory _in)\\n private\\n pure\\n returns (\\n uint256,\\n uint256,\\n RLPItemType\\n )\\n {\\n // Short-circuit if there's nothing to decode, note that we perform this check when\\n // the user creates an RLP item via toRLPItem, but it's always possible for them to bypass\\n // that function and create an RLP item directly. So we need to check this anyway.\\n require(\\n _in.length > 0,\\n \\\"RLPReader: length of an RLP item must be greater than zero to be decodable\\\"\\n );\\n\\n MemoryPointer ptr = _in.ptr;\\n uint256 prefix;\\n assembly {\\n prefix := byte(0, mload(ptr))\\n }\\n\\n if (prefix <= 0x7f) {\\n // Single byte.\\n return (0, 1, RLPItemType.DATA_ITEM);\\n } else if (prefix <= 0xb7) {\\n // Short string.\\n\\n // slither-disable-next-line variable-scope\\n uint256 strLen = prefix - 0x80;\\n\\n require(\\n _in.length > strLen,\\n \\\"RLPReader: length of content must be greater than string length (short string)\\\"\\n );\\n\\n bytes1 firstByteOfContent;\\n assembly {\\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\\n }\\n\\n require(\\n strLen != 1 || firstByteOfContent >= 0x80,\\n \\\"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\\\"\\n );\\n\\n return (1, strLen, RLPItemType.DATA_ITEM);\\n } else if (prefix <= 0xbf) {\\n // Long string.\\n uint256 lenOfStrLen = prefix - 0xb7;\\n\\n require(\\n _in.length > lenOfStrLen,\\n \\\"RLPReader: length of content must be > than length of string length (long string)\\\"\\n );\\n\\n bytes1 firstByteOfContent;\\n assembly {\\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\\n }\\n\\n require(\\n firstByteOfContent != 0x00,\\n \\\"RLPReader: length of content must not have any leading zeros (long string)\\\"\\n );\\n\\n uint256 strLen;\\n assembly {\\n strLen := shr(sub(256, mul(8, lenOfStrLen)), mload(add(ptr, 1)))\\n }\\n\\n require(\\n strLen > 55,\\n \\\"RLPReader: length of content must be greater than 55 bytes (long string)\\\"\\n );\\n\\n require(\\n _in.length > lenOfStrLen + strLen,\\n \\\"RLPReader: length of content must be greater than total length (long string)\\\"\\n );\\n\\n return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM);\\n } else if (prefix <= 0xf7) {\\n // Short list.\\n // slither-disable-next-line variable-scope\\n uint256 listLen = prefix - 0xc0;\\n\\n require(\\n _in.length > listLen,\\n \\\"RLPReader: length of content must be greater than list length (short list)\\\"\\n );\\n\\n return (1, listLen, RLPItemType.LIST_ITEM);\\n } else {\\n // Long list.\\n uint256 lenOfListLen = prefix - 0xf7;\\n\\n require(\\n _in.length > lenOfListLen,\\n \\\"RLPReader: length of content must be > than length of list length (long list)\\\"\\n );\\n\\n bytes1 firstByteOfContent;\\n assembly {\\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\\n }\\n\\n require(\\n firstByteOfContent != 0x00,\\n \\\"RLPReader: length of content must not have any leading zeros (long list)\\\"\\n );\\n\\n uint256 listLen;\\n assembly {\\n listLen := shr(sub(256, mul(8, lenOfListLen)), mload(add(ptr, 1)))\\n }\\n\\n require(\\n listLen > 55,\\n \\\"RLPReader: length of content must be greater than 55 bytes (long list)\\\"\\n );\\n\\n require(\\n _in.length > lenOfListLen + listLen,\\n \\\"RLPReader: length of content must be greater than total length (long list)\\\"\\n );\\n\\n return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM);\\n }\\n }\\n\\n /**\\n * @notice Copies the bytes from a memory location.\\n *\\n * @param _src Pointer to the location to read from.\\n * @param _offset Offset to start reading from.\\n * @param _length Number of bytes to read.\\n *\\n * @return Copied bytes.\\n */\\n function _copy(\\n MemoryPointer _src,\\n uint256 _offset,\\n uint256 _length\\n ) private pure returns (bytes memory) {\\n bytes memory out = new bytes(_length);\\n if (_length == 0) {\\n return out;\\n }\\n\\n // Mostly based on Solidity's copy_memory_to_memory:\\n // solhint-disable max-line-length\\n // https://github.com/ethereum/solidity/blob/34dd30d71b4da730488be72ff6af7083cf2a91f6/libsolidity/codegen/YulUtilFunctions.cpp#L102-L114\\n uint256 src = MemoryPointer.unwrap(_src) + _offset;\\n assembly {\\n let dest := add(out, 32)\\n let i := 0\\n for {\\n\\n } lt(i, _length) {\\n i := add(i, 32)\\n } {\\n mstore(add(dest, i), mload(add(src, i)))\\n }\\n\\n if gt(i, _length) {\\n mstore(add(dest, _length), 0)\\n }\\n }\\n\\n return out;\\n }\\n}\\n\",\"keccak256\":\"0x50763c897f0fe84cb067985ec4d7c5721ce9004a69cf0327f96f8982ee8ca412\",\"license\":\"MIT\"},\"@eth-optimism/contracts-bedrock/contracts/libraries/trie/MerkleTrie.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { Bytes } from \\\"../Bytes.sol\\\";\\nimport { RLPReader } from \\\"../rlp/RLPReader.sol\\\";\\n\\n/**\\n * @title MerkleTrie\\n * @notice MerkleTrie is a small library for verifying standard Ethereum Merkle-Patricia trie\\n * inclusion proofs. By default, this library assumes a hexary trie. One can change the\\n * trie radix constant to support other trie radixes.\\n */\\nlibrary MerkleTrie {\\n /**\\n * @notice Struct representing a node in the trie.\\n *\\n * @custom:field encoded The RLP-encoded node.\\n * @custom:field decoded The RLP-decoded node.\\n */\\n struct TrieNode {\\n bytes encoded;\\n RLPReader.RLPItem[] decoded;\\n }\\n\\n /**\\n * @notice Determines the number of elements per branch node.\\n */\\n uint256 internal constant TREE_RADIX = 16;\\n\\n /**\\n * @notice Branch nodes have TREE_RADIX elements and one value element.\\n */\\n uint256 internal constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;\\n\\n /**\\n * @notice Leaf nodes and extension nodes have two elements, a `path` and a `value`.\\n */\\n uint256 internal constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;\\n\\n /**\\n * @notice Prefix for even-nibbled extension node paths.\\n */\\n uint8 internal constant PREFIX_EXTENSION_EVEN = 0;\\n\\n /**\\n * @notice Prefix for odd-nibbled extension node paths.\\n */\\n uint8 internal constant PREFIX_EXTENSION_ODD = 1;\\n\\n /**\\n * @notice Prefix for even-nibbled leaf node paths.\\n */\\n uint8 internal constant PREFIX_LEAF_EVEN = 2;\\n\\n /**\\n * @notice Prefix for odd-nibbled leaf node paths.\\n */\\n uint8 internal constant PREFIX_LEAF_ODD = 3;\\n\\n /**\\n * @notice Verifies a proof that a given key/value pair is present in the trie.\\n *\\n * @param _key Key of the node to search for, as a hex string.\\n * @param _value Value of the node to search for, as a hex string.\\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\\n * nodes that make a path down to the target node.\\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\\n * correctly constructed.\\n *\\n * @return Whether or not the proof is valid.\\n */\\n function verifyInclusionProof(\\n bytes memory _key,\\n bytes memory _value,\\n bytes[] memory _proof,\\n bytes32 _root\\n ) internal pure returns (bool) {\\n return Bytes.equal(_value, get(_key, _proof, _root));\\n }\\n\\n /**\\n * @notice Retrieves the value associated with a given key.\\n *\\n * @param _key Key to search for, as hex bytes.\\n * @param _proof Merkle trie inclusion proof for the key.\\n * @param _root Known root of the Merkle trie.\\n *\\n * @return Value of the key if it exists.\\n */\\n function get(\\n bytes memory _key,\\n bytes[] memory _proof,\\n bytes32 _root\\n ) internal pure returns (bytes memory) {\\n require(_key.length > 0, \\\"MerkleTrie: empty key\\\");\\n\\n TrieNode[] memory proof = _parseProof(_proof);\\n bytes memory key = Bytes.toNibbles(_key);\\n bytes memory currentNodeID = abi.encodePacked(_root);\\n uint256 currentKeyIndex = 0;\\n\\n // Proof is top-down, so we start at the first element (root).\\n for (uint256 i = 0; i < proof.length; i++) {\\n TrieNode memory currentNode = proof[i];\\n\\n // Key index should never exceed total key length or we'll be out of bounds.\\n require(\\n currentKeyIndex <= key.length,\\n \\\"MerkleTrie: key index exceeds total key length\\\"\\n );\\n\\n if (currentKeyIndex == 0) {\\n // First proof element is always the root node.\\n require(\\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\\n \\\"MerkleTrie: invalid root hash\\\"\\n );\\n } else if (currentNode.encoded.length >= 32) {\\n // Nodes 32 bytes or larger are hashed inside branch nodes.\\n require(\\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\\n \\\"MerkleTrie: invalid large internal hash\\\"\\n );\\n } else {\\n // Nodes smaller than 32 bytes aren't hashed.\\n require(\\n Bytes.equal(currentNode.encoded, currentNodeID),\\n \\\"MerkleTrie: invalid internal node hash\\\"\\n );\\n }\\n\\n if (currentNode.decoded.length == BRANCH_NODE_LENGTH) {\\n if (currentKeyIndex == key.length) {\\n // Value is the last element of the decoded list (for branch nodes). There's\\n // some ambiguity in the Merkle trie specification because bytes(0) is a\\n // valid value to place into the trie, but for branch nodes bytes(0) can exist\\n // even when the value wasn't explicitly placed there. Geth treats a value of\\n // bytes(0) as \\\"key does not exist\\\" and so we do the same.\\n bytes memory value = RLPReader.readBytes(currentNode.decoded[TREE_RADIX]);\\n require(\\n value.length > 0,\\n \\\"MerkleTrie: value length must be greater than zero (branch)\\\"\\n );\\n\\n // Extra proof elements are not allowed.\\n require(\\n i == proof.length - 1,\\n \\\"MerkleTrie: value node must be last node in proof (branch)\\\"\\n );\\n\\n return value;\\n } else {\\n // We're not at the end of the key yet.\\n // Figure out what the next node ID should be and continue.\\n uint8 branchKey = uint8(key[currentKeyIndex]);\\n RLPReader.RLPItem memory nextNode = currentNode.decoded[branchKey];\\n currentNodeID = _getNodeID(nextNode);\\n currentKeyIndex += 1;\\n }\\n } else if (currentNode.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) {\\n bytes memory path = _getNodePath(currentNode);\\n uint8 prefix = uint8(path[0]);\\n uint8 offset = 2 - (prefix % 2);\\n bytes memory pathRemainder = Bytes.slice(path, offset);\\n bytes memory keyRemainder = Bytes.slice(key, currentKeyIndex);\\n uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder);\\n\\n // Whether this is a leaf node or an extension node, the path remainder MUST be a\\n // prefix of the key remainder (or be equal to the key remainder) or the proof is\\n // considered invalid.\\n require(\\n pathRemainder.length == sharedNibbleLength,\\n \\\"MerkleTrie: path remainder must share all nibbles with key\\\"\\n );\\n\\n if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) {\\n // Prefix of 2 or 3 means this is a leaf node. For the leaf node to be valid,\\n // the key remainder must be exactly equal to the path remainder. We already\\n // did the necessary byte comparison, so it's more efficient here to check that\\n // the key remainder length equals the shared nibble length, which implies\\n // equality with the path remainder (since we already did the same check with\\n // the path remainder and the shared nibble length).\\n require(\\n keyRemainder.length == sharedNibbleLength,\\n \\\"MerkleTrie: key remainder must be identical to path remainder\\\"\\n );\\n\\n // Our Merkle Trie is designed specifically for the purposes of the Ethereum\\n // state trie. Empty values are not allowed in the state trie, so we can safely\\n // say that if the value is empty, the key should not exist and the proof is\\n // invalid.\\n bytes memory value = RLPReader.readBytes(currentNode.decoded[1]);\\n require(\\n value.length > 0,\\n \\\"MerkleTrie: value length must be greater than zero (leaf)\\\"\\n );\\n\\n // Extra proof elements are not allowed.\\n require(\\n i == proof.length - 1,\\n \\\"MerkleTrie: value node must be last node in proof (leaf)\\\"\\n );\\n\\n return value;\\n } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {\\n // Prefix of 0 or 1 means this is an extension node. We move onto the next node\\n // in the proof and increment the key index by the length of the path remainder\\n // which is equal to the shared nibble length.\\n currentNodeID = _getNodeID(currentNode.decoded[1]);\\n currentKeyIndex += sharedNibbleLength;\\n } else {\\n revert(\\\"MerkleTrie: received a node with an unknown prefix\\\");\\n }\\n } else {\\n revert(\\\"MerkleTrie: received an unparseable node\\\");\\n }\\n }\\n\\n revert(\\\"MerkleTrie: ran out of proof elements\\\");\\n }\\n\\n /**\\n * @notice Parses an array of proof elements into a new array that contains both the original\\n * encoded element and the RLP-decoded element.\\n *\\n * @param _proof Array of proof elements to parse.\\n *\\n * @return Proof parsed into easily accessible structs.\\n */\\n function _parseProof(bytes[] memory _proof) private pure returns (TrieNode[] memory) {\\n uint256 length = _proof.length;\\n TrieNode[] memory proof = new TrieNode[](length);\\n for (uint256 i = 0; i < length; ) {\\n proof[i] = TrieNode({ encoded: _proof[i], decoded: RLPReader.readList(_proof[i]) });\\n unchecked {\\n ++i;\\n }\\n }\\n return proof;\\n }\\n\\n /**\\n * @notice Picks out the ID for a node. Node ID is referred to as the \\\"hash\\\" within the\\n * specification, but nodes < 32 bytes are not actually hashed.\\n *\\n * @param _node Node to pull an ID for.\\n *\\n * @return ID for the node, depending on the size of its contents.\\n */\\n function _getNodeID(RLPReader.RLPItem memory _node) private pure returns (bytes memory) {\\n return _node.length < 32 ? RLPReader.readRawBytes(_node) : RLPReader.readBytes(_node);\\n }\\n\\n /**\\n * @notice Gets the path for a leaf or extension node.\\n *\\n * @param _node Node to get a path for.\\n *\\n * @return Node path, converted to an array of nibbles.\\n */\\n function _getNodePath(TrieNode memory _node) private pure returns (bytes memory) {\\n return Bytes.toNibbles(RLPReader.readBytes(_node.decoded[0]));\\n }\\n\\n /**\\n * @notice Utility; determines the number of nibbles shared between two nibble arrays.\\n *\\n * @param _a First nibble array.\\n * @param _b Second nibble array.\\n *\\n * @return Number of shared nibbles.\\n */\\n function _getSharedNibbleLength(bytes memory _a, bytes memory _b)\\n private\\n pure\\n returns (uint256)\\n {\\n uint256 shared;\\n uint256 max = (_a.length < _b.length) ? _a.length : _b.length;\\n for (; shared < max && _a[shared] == _b[shared]; ) {\\n unchecked {\\n ++shared;\\n }\\n }\\n return shared;\\n }\\n}\\n\",\"keccak256\":\"0xd27fc945d6dd2821636d840f3766f817823c8e9fbfdb87c2da7c73e4292d2f7f\",\"license\":\"MIT\"},\"@eth-optimism/contracts-bedrock/contracts/libraries/trie/SecureMerkleTrie.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/* Library Imports */\\nimport { MerkleTrie } from \\\"./MerkleTrie.sol\\\";\\n\\n/**\\n * @title SecureMerkleTrie\\n * @notice SecureMerkleTrie is a thin wrapper around the MerkleTrie library that hashes the input\\n * keys. Ethereum's state trie hashes input keys before storing them.\\n */\\nlibrary SecureMerkleTrie {\\n /**\\n * @notice Verifies a proof that a given key/value pair is present in the Merkle trie.\\n *\\n * @param _key Key of the node to search for, as a hex string.\\n * @param _value Value of the node to search for, as a hex string.\\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\\n * nodes that make a path down to the target node.\\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\\n * correctly constructed.\\n *\\n * @return Whether or not the proof is valid.\\n */\\n function verifyInclusionProof(\\n bytes memory _key,\\n bytes memory _value,\\n bytes[] memory _proof,\\n bytes32 _root\\n ) internal pure returns (bool) {\\n bytes memory key = _getSecureKey(_key);\\n return MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);\\n }\\n\\n /**\\n * @notice Retrieves the value associated with a given key.\\n *\\n * @param _key Key to search for, as hex bytes.\\n * @param _proof Merkle trie inclusion proof for the key.\\n * @param _root Known root of the Merkle trie.\\n *\\n * @return Value of the key if it exists.\\n */\\n function get(\\n bytes memory _key,\\n bytes[] memory _proof,\\n bytes32 _root\\n ) internal pure returns (bytes memory) {\\n bytes memory key = _getSecureKey(_key);\\n return MerkleTrie.get(key, _proof, _root);\\n }\\n\\n /**\\n * @notice Computes the hashed version of the input key.\\n *\\n * @param _key Key to hash.\\n *\\n * @return Hashed version of the key.\\n */\\n function _getSecureKey(bytes memory _key) private pure returns (bytes memory) {\\n return abi.encodePacked(keccak256(_key));\\n }\\n}\\n\",\"keccak256\":\"0x61b03a03779cb1f75cea3b88af16fdfd10629029b4b2d6be5238e71af8ef1b5f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling 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\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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 _nonReentrantBefore();\\n _;\\n _nonReentrantAfter();\\n }\\n\\n function _nonReentrantBefore() private {\\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n }\\n\\n function _nonReentrantAfter() private {\\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 /**\\n * @dev Returns true if the reentrancy guard is currently set to \\\"entered\\\", which indicates there is a\\n * `nonReentrant` function in the call stack.\\n */\\n function _reentrancyGuardEntered() internal view returns (bool) {\\n return _status == _ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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 * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, \\\"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(address target, bytes memory data, uint256 value) 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 (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or 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 _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\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\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts/SonneMerkleDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.19;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {SecureMerkleTrie} from \\\"@eth-optimism/contracts-bedrock/contracts/libraries/trie/SecureMerkleTrie.sol\\\";\\nimport {RLPReader} from \\\"@eth-optimism/contracts-bedrock/contracts/libraries/rlp/RLPReader.sol\\\";\\nimport {ISonneMerkleDistributor} from \\\"./interfaces/ISonneMerkleDistributor.sol\\\";\\n\\n/// @title Sonne Finance Merkle tree-based rewards distributor\\n/// @notice Contract to distribute rewards on BASE network to Sonne Finance Optimism stakers\\ncontract SonneMerkleDistributor is\\n ReentrancyGuard,\\n Ownable,\\n ISonneMerkleDistributor\\n{\\n using SafeERC20 for IERC20;\\n\\n struct Reward {\\n uint256 balance; // amount of reward tokens held in this reward\\n bytes32 merkleRoot; // root of claims merkle tree\\n uint256 withdrawUnlockTime; // time after which owner can withdraw remaining rewards\\n uint256 ratio; // ratio of rewards to be distributed per one staked token on OP\\n mapping(bytes32 => bool) leafClaimed; // mapping of leafes that already claimed\\n }\\n\\n IERC20 public immutable rewardToken;\\n uint256[] public rewards; // a list of all rewards\\n\\n mapping(uint256 => Reward) public Rewards; // mapping between blockNumber => Reward\\n mapping(address => address) public delegatorAddresses;\\n\\n /// mapping to allow msg.sender to claim on behalf of a delegators address\\n\\n /// @notice Contract constructor to initialize rewardToken\\n /// @param _rewardToken The reward token to be distributed\\n constructor(IERC20 _rewardToken) {\\n require(address(_rewardToken) != address(0), \\\"Token cannot be zero\\\");\\n rewardToken = _rewardToken;\\n }\\n\\n /// @notice Sets a delegator address for a given recipient\\n /// @param _recipient original eligible recipient address\\n /// @param _delegator The address that sould claim on behalf of the owner\\n function setDelegator(\\n address _recipient,\\n address _delegator\\n ) external onlyOwner {\\n require(\\n _recipient != address(0) && _delegator != address(0),\\n \\\"Invalid address provided\\\"\\n );\\n delegatorAddresses[_delegator] = _recipient;\\n }\\n\\n /// @notice Creates a new Reward struct for a rewards distribution\\n /// @param amount The amount of reward tokens to deposit\\n /// @param merkleRoot The merkle root of the distribution tree\\n /// @param blockNumber The block number for the Reward\\n /// @param withdrawUnlockTime The timestamp after which withdrawals by owner are allowed\\n /// @param totalStakedBalance Total staked balance of the merkleRoot (computed off-chain)\\n function addReward(\\n uint256 amount,\\n bytes32 merkleRoot,\\n uint256 blockNumber,\\n uint256 withdrawUnlockTime,\\n uint256 totalStakedBalance\\n ) external onlyOwner {\\n require(merkleRoot != bytes32(0), \\\"Merkle root cannot be zero\\\");\\n\\n // creates a new reward struct tied to the blocknumber the merkleProof was created at\\n Reward storage reward = Rewards[blockNumber];\\n\\n require(\\n reward.merkleRoot == bytes32(0),\\n \\\"Merkle root was already posted\\\"\\n );\\n uint256 balance = rewardToken.balanceOf(msg.sender);\\n require(\\n amount > 0 && amount <= balance,\\n \\\"Invalid amount or insufficient balance\\\"\\n );\\n\\n // transfer rewardToken from the distributor to the contract\\n rewardToken.safeTransferFrom(msg.sender, address(this), amount);\\n\\n // record Reward in stable storage\\n reward.balance = amount;\\n reward.merkleRoot = merkleRoot;\\n reward.withdrawUnlockTime = withdrawUnlockTime;\\n reward.ratio = (amount * 1e18) / (totalStakedBalance);\\n rewards.push(blockNumber);\\n emit NewMerkle(\\n msg.sender,\\n address(rewardToken),\\n amount,\\n merkleRoot,\\n blockNumber,\\n withdrawUnlockTime\\n );\\n }\\n\\n /// @notice Allows to withdraw available funds to owner after unlock time\\n /// @param blockNumber The block number for the Reward\\n /// @param amount The amount to withdraw\\n function withdrawFunds(\\n uint256 blockNumber,\\n uint256 amount\\n ) external onlyOwner {\\n Reward storage reward = Rewards[blockNumber];\\n require(\\n block.timestamp >= reward.withdrawUnlockTime,\\n \\\"Rewards may not be withdrawn\\\"\\n );\\n require(amount <= reward.balance, \\\"Insufficient balance\\\");\\n\\n // update Rewards record\\n reward.balance = reward.balance -= amount;\\n\\n // transfer rewardToken back to owner\\n rewardToken.safeTransfer(msg.sender, amount);\\n emit MerkleFundUpdate(\\n msg.sender,\\n reward.merkleRoot,\\n blockNumber,\\n amount,\\n true\\n );\\n }\\n\\n /// @notice Claims the specified amount for an account if valid\\n /// @dev Checks proofs and claims tracking before transferring rewardTokens\\n /// @param blockNumber The block number for the Reward\\n /// @param proof The merkle proof for the claim\\n function claim(\\n uint256 blockNumber,\\n bytes[] calldata proof\\n ) external nonReentrant {\\n Reward storage reward = Rewards[blockNumber];\\n require(reward.merkleRoot != bytes32(0), \\\"Reward not found\\\");\\n\\n // Check if the delegatorAddresses includes the account\\n // The delegatorAddresses mapping allows for an account to delegate its claim ability to another address\\n // This can be useful in scenarios where the target recipient might not have the ability to directly interact\\n // with the BASE network contract (e.g. a smart contract with a different address)\\n address recipient = delegatorAddresses[msg.sender] != address(0)\\n ? delegatorAddresses[msg.sender]\\n : msg.sender;\\n\\n // Assuming slotNr is 2 as per your previous function\\n bytes32 key = keccak256(abi.encode(recipient, uint256(2)));\\n\\n //Get the amount of the key from the merkel tree\\n uint256 amount = _getValueFromMerkleTree(reward.merkleRoot, key, proof);\\n\\n // calculate the reward based on the ratio\\n uint256 rewardAmount = (amount * reward.ratio) / 1e18; // TODO check if there is a loss of precision possible here\\n\\n require(\\n reward.balance >= rewardAmount,\\n \\\"Claim under-funded by funder.\\\"\\n );\\n require(\\n Rewards[blockNumber].leafClaimed[key] == false,\\n \\\"Already claimed\\\"\\n );\\n\\n // marks the leaf as claimed\\n reward.leafClaimed[key] = true;\\n\\n // Subtract the rewardAmount, not the amount\\n reward.balance = reward.balance - rewardAmount;\\n\\n //Send reward tokens to the recipient\\n rewardToken.safeTransfer(recipient, rewardAmount);\\n\\n emit MerkleClaim(\\n recipient,\\n address(rewardToken),\\n blockNumber,\\n rewardAmount\\n );\\n }\\n\\n /// @notice Checks if a claim is valid and claimable\\n /// @param blockNumber The block number for the Reward\\n /// @param account The address of the account claiming\\n /// @param proof The merkle proof for the claim\\n /// @return A bool indicating if the claim is valid and claimable\\n function isClaimable(\\n uint256 blockNumber,\\n address account,\\n bytes[] calldata proof\\n ) external view returns (bool) {\\n bytes32 merkleRoot = Rewards[blockNumber].merkleRoot;\\n\\n // At the staking contract, the balances are stored in a mapping (address => uint256) at storage slot 2\\n bytes32 leaf = keccak256(abi.encode(account, uint256(2)));\\n\\n if (merkleRoot == 0) return false;\\n return\\n !Rewards[blockNumber].leafClaimed[leaf] &&\\n _getValueFromMerkleTree(merkleRoot, leaf, proof) > 0;\\n }\\n\\n /// @dev Uses SecureMerkleTrie Library to extract the value from the Merkle proof provided by the user\\n /// @param merkleRoot the merkle root\\n /// @param key the key of the leaf => keccak256(address,2)\\n /// @return result The converted uint256 value as stored in the slot on OP\\n function _getValueFromMerkleTree(\\n bytes32 merkleRoot,\\n bytes32 key,\\n bytes[] calldata proof\\n ) internal pure returns (uint256 result) {\\n // Uses SecureMerkleTrie Library to extract the value from the Merkle proof provided by the user\\n // Reverts if Merkle proof verification fails\\n bytes memory data = RLPReader.readBytes(\\n SecureMerkleTrie.get(abi.encodePacked(key), proof, merkleRoot)\\n );\\n\\n for (uint256 i = 0; i < data.length; i++) {\\n result = result * 256 + uint8(data[i]);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x24a21883e5b5e69784f51f50a81ce2004026d1076058c0f2c035f4e6090969ed\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ISonneMerkleDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.19;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\n\\ninterface ISonneMerkleDistributor {\\n event NewMerkle(\\n address indexed creator,\\n address indexed rewardToken,\\n uint256 amount,\\n bytes32 indexed merkleRoot,\\n uint256 blockNr,\\n uint256 withdrawUnlockTime\\n );\\n event MerkleFundUpdate(\\n address indexed funder,\\n bytes32 indexed merkleRoot,\\n uint256 blockNr,\\n uint256 amount,\\n bool withdrawal\\n );\\n event MerkleClaim(address indexed claimer, address indexed rewardToken, uint256 indexed blockNr, uint256 amount);\\n\\n function rewardToken() external view returns (IERC20);\\n\\n function Rewards(\\n uint256 blockNumber\\n ) external view returns (uint256 balance, bytes32 merkleRoot, uint256 withdrawUnlockTime, uint256 ratio);\\n\\n function delegatorAddresses(address _delegator) external view returns (address originalRecipient);\\n\\n function setDelegator(address _recipient, address _delegator) external;\\n\\n function addReward(\\n uint256 amount,\\n bytes32 merkleRoot,\\n uint256 blockNumber,\\n uint256 withdrawUnlockTime,\\n uint256 totalStakedBalance\\n ) external;\\n\\n function withdrawFunds(uint256 blockNumber, uint256 amount) external;\\n\\n function claim(uint256 blockNumber, bytes[] calldata proof) external;\\n\\n function isClaimable(uint256 blockNumber, address account, bytes[] calldata proof) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xaa6ea729a26b7d515f1f4c9732a955d84253d5c57f68d40d0441f82c0955816a\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b506040516200320138038062003201833981016040819052620000349162000103565b60016000556200004433620000b1565b6001600160a01b0381166200009f5760405162461bcd60e51b815260206004820152601460248201527f546f6b656e2063616e6e6f74206265207a65726f000000000000000000000000604482015260640160405180910390fd5b6001600160a01b031660805262000135565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602082840312156200011657600080fd5b81516001600160a01b03811681146200012e57600080fd5b9392505050565b6080516130866200017b600039600081816101e1015281816104730152818161049d01528181610761015281816108650152818161090d0152610a5201526130866000f3fe608060405234801561001057600080fd5b50600436106100d35760003560e01c80639366452c11610081578063f301af421161005b578063f301af42146101bb578063f7c618c1146101dc578063f8738c251461020357600080fd5b80639366452c14610182578063e525310514610195578063f2fde38b146101a857600080fd5b80636d46379b116100b25780636d46379b14610146578063715018a6146101695780638da5cb5b1461017157600080fd5b8062501e28146100d85780631ce92be5146100ed57806341f891a414610100575b600080fd5b6100eb6100e6366004612c03565b61025a565b005b6100eb6100fb366004612c6b565b61051c565b61012961010e366004612c9e565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610159610154366004612cb9565b6105cd565b604051901515815260200161013d565b6100eb610667565b6001546001600160a01b0316610129565b6100eb610190366004612d13565b61067b565b6100eb6101a3366004612d4e565b61096e565b6100eb6101b6366004612c9e565b610ac9565b6101ce6101c9366004612d70565b610b59565b60405190815260200161013d565b6101297f000000000000000000000000000000000000000000000000000000000000000081565b61023a610211366004612d70565b600360208190526000918252604090912080546001820154600283015492909301549092919084565b60408051948552602085019390935291830152606082015260800161013d565b610262610b7a565b600083815260036020526040902060018101546102c65760405162461bcd60e51b815260206004820152601060248201527f526577617264206e6f7420666f756e640000000000000000000000000000000060448201526064015b60405180910390fd5b336000908152600460205260408120546001600160a01b03166102e95733610303565b336000908152600460205260409020546001600160a01b03165b604080516001600160a01b038316602082015260029181019190915290915060009060600160405160208183030381529060405280519060200120905060006103528460010154838888610bd3565b90506000670de0b6b3a764000085600301548361036f9190612d9f565b6103799190612dcc565b905080856000015410156103cf5760405162461bcd60e51b815260206004820152601d60248201527f436c61696d20756e6465722d66756e6465642062792066756e6465722e00000060448201526064016102bd565b600088815260036020908152604080832086845260040190915290205460ff161561043c5760405162461bcd60e51b815260206004820152600f60248201527f416c726561647920636c61696d6564000000000000000000000000000000000060448201526064016102bd565b60008381526004860160205260409020805460ff191660011790558454610464908290612de0565b855561049a6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168583610c70565b877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b03167fceea116ca90ae38b5f3bcd7482763d0bdd5915faed2146d37b1e3bcd1ea425378460405161050091815260200190565b60405180910390a450505050506105176001600055565b505050565b610524610d19565b6001600160a01b0382161580159061054457506001600160a01b03811615155b6105905760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420616464726573732070726f7669646564000000000000000060448201526064016102bd565b6001600160a01b03908116600090815260046020526040902080549190921673ffffffffffffffffffffffffffffffffffffffff19909116179055565b60008481526003602090815260408083206001015481516001600160a01b038816818501526002818401528251808203840181526060909101909252815191909201208183036106225760009250505061065f565b600087815260036020908152604080832084845260040190915290205460ff1615801561065a5750600061065883838888610bd3565b115b925050505b949350505050565b61066f610d19565b6106796000610d73565b565b610683610d19565b836106d05760405162461bcd60e51b815260206004820152601a60248201527f4d65726b6c6520726f6f742063616e6e6f74206265207a65726f00000000000060448201526064016102bd565b60008381526003602052604090206001810154156107305760405162461bcd60e51b815260206004820152601e60248201527f4d65726b6c6520726f6f742077617320616c726561647920706f73746564000060448201526064016102bd565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156107b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d49190612df3565b90506000871180156107e65750808711155b6108585760405162461bcd60e51b815260206004820152602660248201527f496e76616c696420616d6f756e74206f7220696e73756666696369656e74206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016102bd565b61088d6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308a610dd2565b8682556001820186905560028201849055826108b188670de0b6b3a7640000612d9f565b6108bb9190612dcc565b6003830155600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace01859055604080518881526020810187905290810185905286907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169033907f4993e379e2a0a87975314480436d8f2de32d291a64892cb63cdb0839d09044369060600160405180910390a450505050505050565b610976610d19565b600082815260036020526040902060028101544210156109d85760405162461bcd60e51b815260206004820152601c60248201527f52657761726473206d6179206e6f742062652077697468647261776e0000000060448201526064016102bd565b8054821115610a295760405162461bcd60e51b815260206004820152601460248201527f496e73756666696369656e742062616c616e636500000000000000000000000060448201526064016102bd565b81816000016000828254610a3d9190612de0565b9182905550825550610a796001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163384610c70565b6001808201546040805186815260208101869052908101929092529033907f210aece5a2bb3ac8bbec4d3bd83444123ef037a899b89d617e735799f983e6b39060600160405180910390a3505050565b610ad1610d19565b6001600160a01b038116610b4d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102bd565b610b5681610d73565b50565b60028181548110610b6957600080fd5b600091825260209091200154905081565b600260005403610bcc5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016102bd565b6002600055565b600080610c14610c0f86604051602001610bef91815260200190565b60408051601f19818403018152919052610c098688612e53565b89610e29565b610e4e565b905060005b8151811015610c6657818181518110610c3457610c34612f28565b016020015160f81c610c4884610100612d9f565b610c529190612f3e565b925080610c5e81612f51565b915050610c19565b5050949350505050565b6040516001600160a01b0383166024820152604481018290526105179084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610e67565b6001546001600160a01b031633146106795760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102bd565b600180546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6040516001600160a01b0380851660248301528316604482015260648101829052610e239085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610cb5565b50505050565b60606000610e3685610f4f565b9050610e43818585610f81565b9150505b9392505050565b6060610e61610e5c8361189d565b611959565b92915050565b6000610ebc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611a8e9092919063ffffffff16565b9050805160001480610edd575080806020019051810190610edd9190612f6a565b6105175760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016102bd565b60608180519060200120604051602001610f6b91815260200190565b6040516020818303038152906040529050919050565b60606000845111610fd45760405162461bcd60e51b815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b6579000000000000000000000060448201526064016102bd565b6000610fdf84611a9d565b90506000610fec86611b8c565b905060008460405160200161100391815260200190565b60405160208183030381529060405290506000805b845181101561182e57600085828151811061103557611035612f28565b6020026020010151905084518311156110b65760405162461bcd60e51b815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e67746800000000000000000000000000000000000060648201526084016102bd565b826000036111555780518051602091820120604051611104926110de92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b6111505760405162461bcd60e51b815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f74206861736800000060448201526064016102bd565b611278565b8051516020116111f1578051805160209182012060405161117f926110de92910190815260200190565b6111505760405162461bcd60e51b815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c20686173680000000000000000000000000000000000000000000000000060648201526084016102bd565b8051845160208087019190912082519190920120146112785760405162461bcd60e51b815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f652068617368000000000000000000000000000000000000000000000000000060648201526084016102bd565b61128460106001612f3e565b8160200151510361143157845183036113c95760006112c082602001516010815181106112b3576112b3612f28565b6020026020010151611959565b905060008151116113395760405162461bcd60e51b815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e636829000000000060648201526084016102bd565b600187516113479190612de0565b83146113bb5760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e63682900000000000060648201526084016102bd565b9650610e4795505050505050565b60008584815181106113dd576113dd612f28565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061140857611408612f28565b6020026020010151905061141b81611bef565b9550611428600186612f3e565b9450505061181b565b6002816020015151036117ad57600061144982611c14565b905060008160008151811061146057611460612f28565b016020015160f81c90506000611477600283612f8c565b611482906002612fae565b90506000611493848360ff16611c38565b905060006114a18a89611c38565b905060006114af8383611c6e565b9050808351146115275760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b657900000000000060648201526084016102bd565b60ff85166002148061153c575060ff85166003145b156116e257808251146115b75760405162461bcd60e51b815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e64657200000060648201526084016102bd565b60006115d388602001516001815181106112b3576112b3612f28565b9050600081511161164c5760405162461bcd60e51b815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c656166290000000000000060648201526084016102bd565b60018d5161165a9190612de0565b89146116ce5760405162461bcd60e51b815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c65616629000000000000000060648201526084016102bd565b9c50610e479b505050505050505050505050565b60ff851615806116f5575060ff85166001145b1561173457611721876020015160018151811061171457611714612f28565b6020026020010151611bef565b995061172d818a612f3e565b98506117a2565b60405162461bcd60e51b815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e20707265666978000000000000000000000000000060648201526084016102bd565b50505050505061181b565b60405162461bcd60e51b815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f646500000000000000000000000000000000000000000000000060648201526084016102bd565b508061182681612f51565b915050611018565b5060405162461bcd60e51b815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e747300000000000000000000000000000000000000000000000000000060648201526084016102bd565b6040805180820190915260008082526020820152600082511161193b5760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f206265606482015269206465636f6461626c6560b01b608482015260a4016102bd565b50604080518082019091528151815260209182019181019190915290565b6060600080600061196985611d05565b91945092509050600081600181111561198457611984612fc7565b146119f75760405162461bcd60e51b815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d0000000000000060648201526084016102bd565b611a018284612f3e565b855114611a765760405162461bcd60e51b815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e64657200000000000000000000000060648201526084016102bd565b611a85856020015184846125c7565b95945050505050565b606061065f8484600085612668565b805160609060008167ffffffffffffffff811115611abd57611abd612e0c565b604051908082528060200260200182016040528015611b0257816020015b6040805180820190915260608082526020820152815260200190600190039081611adb5790505b50905060005b82811015611b84576040518060400160405280868381518110611b2d57611b2d612f28565b60200260200101518152602001611b5c878481518110611b4f57611b4f612f28565b602002602001015161274f565b815250828281518110611b7157611b71612f28565b6020908102919091010152600101611b08565b509392505050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015611be4578060011b82018184015160001a8060041c8253600f811660018301535050600101611bb6565b509295945050505050565b60606020826000015110611c0b57611c0682611959565b610e61565b610e6182612762565b6060610e61611c3383602001516000815181106112b3576112b3612f28565b611b8c565b606082518210611c575750604080516020810190915260008152610e61565b610e478383848651611c699190612de0565b612778565b60008060008351855110611c83578351611c86565b84515b90505b8082108015611cf55750838281518110611ca557611ca5612f28565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858381518110611ce457611ce4612f28565b01602001516001600160f81b031916145b15611b8457816001019150611c89565b600080600080846000015111611d965760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f206265606482015269206465636f6461626c6560b01b608482015260a4016102bd565b6020840151805160001a607f8111611dbb5760006001600094509450945050506125c0565b60b78111611f65576000611dd0608083612de0565b905080876000015111611e715760405162461bcd60e51b815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a4016102bd565b6001838101516001600160f81b0319169082141580611eba57507f80000000000000000000000000000000000000000000000000000000000000006001600160f81b0319821610155b611f525760405162461bcd60e51b815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a4016102bd565b50600195509350600092506125c0915050565b60bf8111612233576000611f7a60b783612de0565b90508087600001511161201b5760405162461bcd60e51b815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a4016102bd565b60018301516001600160f81b03191660008190036120c75760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a4016102bd565b600184015160088302610100031c603781116121715760405162461bcd60e51b815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a4016102bd565b61217b8184612f3e565b8951116122165760405162461bcd60e51b815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a4016102bd565b612221836001612f3e565b97509550600094506125c09350505050565b60f781116122fa57600061224860c083612de0565b9050808760000151116122e95760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a4016102bd565b6001955093508492506125c0915050565b600061230760f783612de0565b9050808760000151116123a85760405162461bcd60e51b815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a4016102bd565b60018301516001600160f81b03191660008190036124545760405162461bcd60e51b815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a4016102bd565b600184015160088302610100031c603781116124fe5760405162461bcd60e51b815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a4016102bd565b6125088184612f3e565b8951116125a35760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a4016102bd565b6125ae836001612f3e565b97509550600194506125c09350505050565b9193909250565b606060008267ffffffffffffffff8111156125e4576125e4612e0c565b6040519080825280601f01601f19166020018201604052801561260e576020820181803683370190505b50905082600003612620579050610e47565b600061262c8587612f3e565b90506020820160005b8581101561264d578281015182820152602001612635565b8581111561265c576000868301525b50919695505050505050565b6060824710156126e05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016102bd565b600080866001600160a01b031685876040516126fc9190613001565b60006040518083038185875af1925050503d8060008114612739576040519150601f19603f3d011682016040523d82523d6000602084013e61273e565b606091505b509150915061065a878383876128e4565b6060610e6161275d8361189d565b61295d565b6060610e618260200151600084600001516125c7565b60608182601f0110156127cd5760405162461bcd60e51b815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016102bd565b82828401101561281f5760405162461bcd60e51b815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016102bd565b818301845110156128725760405162461bcd60e51b815260206004820152601160248201527f736c6963655f6f75744f66426f756e647300000000000000000000000000000060448201526064016102bd565b60608215801561289157604051915060008252602082016040526128db565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156128ca5780518352602092830192016128b2565b5050858452601f01601f1916604052505b50949350505050565b6060831561295357825160000361294c576001600160a01b0385163b61294c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102bd565b508161065f565b61065f8383612b8d565b6060600080600061296d85611d05565b91945092509050600181600181111561298857612988612fc7565b146129fb5760405162461bcd60e51b815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d000000000000000060648201526084016102bd565b8451612a078385612f3e565b14612a7a5760405162461bcd60e51b815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e646572000000000000000000000000000060648201526084016102bd565b6040805160208082526104208201909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081612a935790505090506000845b8751811015612b8157600080612b066040518060400160405280858d60000151612aea9190612de0565b8152602001858d60200151612aff9190612f3e565b9052611d05565b509150915060405180604001604052808383612b229190612f3e565b8152602001848c60200151612b379190612f3e565b815250858581518110612b4c57612b4c612f28565b6020908102919091010152612b62600185612f3e565b9350612b6e8183612f3e565b612b789084612f3e565b92505050612ac0565b50815295945050505050565b815115612b9d5781518083602001fd5b8060405162461bcd60e51b81526004016102bd919061301d565b60008083601f840112612bc957600080fd5b50813567ffffffffffffffff811115612be157600080fd5b6020830191508360208260051b8501011115612bfc57600080fd5b9250929050565b600080600060408486031215612c1857600080fd5b83359250602084013567ffffffffffffffff811115612c3657600080fd5b612c4286828701612bb7565b9497909650939450505050565b80356001600160a01b0381168114612c6657600080fd5b919050565b60008060408385031215612c7e57600080fd5b612c8783612c4f565b9150612c9560208401612c4f565b90509250929050565b600060208284031215612cb057600080fd5b610e4782612c4f565b60008060008060608587031215612ccf57600080fd5b84359350612cdf60208601612c4f565b9250604085013567ffffffffffffffff811115612cfb57600080fd5b612d0787828801612bb7565b95989497509550505050565b600080600080600060a08688031215612d2b57600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060408385031215612d6157600080fd5b50508035926020909101359150565b600060208284031215612d8257600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e6157610e61612d89565b634e487b7160e01b600052601260045260246000fd5b600082612ddb57612ddb612db6565b500490565b81810381811115610e6157610e61612d89565b600060208284031215612e0557600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612e4b57612e4b612e0c565b604052919050565b600067ffffffffffffffff80841115612e6e57612e6e612e0c565b8360051b6020612e7f818301612e22565b868152918501918181019036841115612e9757600080fd5b865b84811015612f1c57803586811115612eb15760008081fd5b8801601f3681830112612ec45760008081fd5b813588811115612ed657612ed6612e0c565b612ee7818301601f19168801612e22565b91508082523687828501011115612efe5760008081fd5b80878401888401376000908201870152845250918301918301612e99565b50979650505050505050565b634e487b7160e01b600052603260045260246000fd5b80820180821115610e6157610e61612d89565b600060018201612f6357612f63612d89565b5060010190565b600060208284031215612f7c57600080fd5b81518015158114610e4757600080fd5b600060ff831680612f9f57612f9f612db6565b8060ff84160691505092915050565b60ff8281168282160390811115610e6157610e61612d89565b634e487b7160e01b600052602160045260246000fd5b60005b83811015612ff8578181015183820152602001612fe0565b50506000910152565b60008251613013818460208701612fdd565b9190910192915050565b602081526000825180602084015261303c816040850160208701612fdd565b601f01601f1916919091016040019291505056fea2646970667358221220ef586eb6a714f1d80c54375ad6c7029882b499d015fab7a74b47a02e7dd863e864736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d35760003560e01c80639366452c11610081578063f301af421161005b578063f301af42146101bb578063f7c618c1146101dc578063f8738c251461020357600080fd5b80639366452c14610182578063e525310514610195578063f2fde38b146101a857600080fd5b80636d46379b116100b25780636d46379b14610146578063715018a6146101695780638da5cb5b1461017157600080fd5b8062501e28146100d85780631ce92be5146100ed57806341f891a414610100575b600080fd5b6100eb6100e6366004612c03565b61025a565b005b6100eb6100fb366004612c6b565b61051c565b61012961010e366004612c9e565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610159610154366004612cb9565b6105cd565b604051901515815260200161013d565b6100eb610667565b6001546001600160a01b0316610129565b6100eb610190366004612d13565b61067b565b6100eb6101a3366004612d4e565b61096e565b6100eb6101b6366004612c9e565b610ac9565b6101ce6101c9366004612d70565b610b59565b60405190815260200161013d565b6101297f000000000000000000000000000000000000000000000000000000000000000081565b61023a610211366004612d70565b600360208190526000918252604090912080546001820154600283015492909301549092919084565b60408051948552602085019390935291830152606082015260800161013d565b610262610b7a565b600083815260036020526040902060018101546102c65760405162461bcd60e51b815260206004820152601060248201527f526577617264206e6f7420666f756e640000000000000000000000000000000060448201526064015b60405180910390fd5b336000908152600460205260408120546001600160a01b03166102e95733610303565b336000908152600460205260409020546001600160a01b03165b604080516001600160a01b038316602082015260029181019190915290915060009060600160405160208183030381529060405280519060200120905060006103528460010154838888610bd3565b90506000670de0b6b3a764000085600301548361036f9190612d9f565b6103799190612dcc565b905080856000015410156103cf5760405162461bcd60e51b815260206004820152601d60248201527f436c61696d20756e6465722d66756e6465642062792066756e6465722e00000060448201526064016102bd565b600088815260036020908152604080832086845260040190915290205460ff161561043c5760405162461bcd60e51b815260206004820152600f60248201527f416c726561647920636c61696d6564000000000000000000000000000000000060448201526064016102bd565b60008381526004860160205260409020805460ff191660011790558454610464908290612de0565b855561049a6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168583610c70565b877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b03167fceea116ca90ae38b5f3bcd7482763d0bdd5915faed2146d37b1e3bcd1ea425378460405161050091815260200190565b60405180910390a450505050506105176001600055565b505050565b610524610d19565b6001600160a01b0382161580159061054457506001600160a01b03811615155b6105905760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420616464726573732070726f7669646564000000000000000060448201526064016102bd565b6001600160a01b03908116600090815260046020526040902080549190921673ffffffffffffffffffffffffffffffffffffffff19909116179055565b60008481526003602090815260408083206001015481516001600160a01b038816818501526002818401528251808203840181526060909101909252815191909201208183036106225760009250505061065f565b600087815260036020908152604080832084845260040190915290205460ff1615801561065a5750600061065883838888610bd3565b115b925050505b949350505050565b61066f610d19565b6106796000610d73565b565b610683610d19565b836106d05760405162461bcd60e51b815260206004820152601a60248201527f4d65726b6c6520726f6f742063616e6e6f74206265207a65726f00000000000060448201526064016102bd565b60008381526003602052604090206001810154156107305760405162461bcd60e51b815260206004820152601e60248201527f4d65726b6c6520726f6f742077617320616c726561647920706f73746564000060448201526064016102bd565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156107b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d49190612df3565b90506000871180156107e65750808711155b6108585760405162461bcd60e51b815260206004820152602660248201527f496e76616c696420616d6f756e74206f7220696e73756666696369656e74206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016102bd565b61088d6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308a610dd2565b8682556001820186905560028201849055826108b188670de0b6b3a7640000612d9f565b6108bb9190612dcc565b6003830155600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace01859055604080518881526020810187905290810185905286907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169033907f4993e379e2a0a87975314480436d8f2de32d291a64892cb63cdb0839d09044369060600160405180910390a450505050505050565b610976610d19565b600082815260036020526040902060028101544210156109d85760405162461bcd60e51b815260206004820152601c60248201527f52657761726473206d6179206e6f742062652077697468647261776e0000000060448201526064016102bd565b8054821115610a295760405162461bcd60e51b815260206004820152601460248201527f496e73756666696369656e742062616c616e636500000000000000000000000060448201526064016102bd565b81816000016000828254610a3d9190612de0565b9182905550825550610a796001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163384610c70565b6001808201546040805186815260208101869052908101929092529033907f210aece5a2bb3ac8bbec4d3bd83444123ef037a899b89d617e735799f983e6b39060600160405180910390a3505050565b610ad1610d19565b6001600160a01b038116610b4d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102bd565b610b5681610d73565b50565b60028181548110610b6957600080fd5b600091825260209091200154905081565b600260005403610bcc5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016102bd565b6002600055565b600080610c14610c0f86604051602001610bef91815260200190565b60408051601f19818403018152919052610c098688612e53565b89610e29565b610e4e565b905060005b8151811015610c6657818181518110610c3457610c34612f28565b016020015160f81c610c4884610100612d9f565b610c529190612f3e565b925080610c5e81612f51565b915050610c19565b5050949350505050565b6040516001600160a01b0383166024820152604481018290526105179084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610e67565b6001546001600160a01b031633146106795760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102bd565b600180546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6040516001600160a01b0380851660248301528316604482015260648101829052610e239085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610cb5565b50505050565b60606000610e3685610f4f565b9050610e43818585610f81565b9150505b9392505050565b6060610e61610e5c8361189d565b611959565b92915050565b6000610ebc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611a8e9092919063ffffffff16565b9050805160001480610edd575080806020019051810190610edd9190612f6a565b6105175760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016102bd565b60608180519060200120604051602001610f6b91815260200190565b6040516020818303038152906040529050919050565b60606000845111610fd45760405162461bcd60e51b815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b6579000000000000000000000060448201526064016102bd565b6000610fdf84611a9d565b90506000610fec86611b8c565b905060008460405160200161100391815260200190565b60405160208183030381529060405290506000805b845181101561182e57600085828151811061103557611035612f28565b6020026020010151905084518311156110b65760405162461bcd60e51b815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e67746800000000000000000000000000000000000060648201526084016102bd565b826000036111555780518051602091820120604051611104926110de92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b6111505760405162461bcd60e51b815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f74206861736800000060448201526064016102bd565b611278565b8051516020116111f1578051805160209182012060405161117f926110de92910190815260200190565b6111505760405162461bcd60e51b815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c20686173680000000000000000000000000000000000000000000000000060648201526084016102bd565b8051845160208087019190912082519190920120146112785760405162461bcd60e51b815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f652068617368000000000000000000000000000000000000000000000000000060648201526084016102bd565b61128460106001612f3e565b8160200151510361143157845183036113c95760006112c082602001516010815181106112b3576112b3612f28565b6020026020010151611959565b905060008151116113395760405162461bcd60e51b815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e636829000000000060648201526084016102bd565b600187516113479190612de0565b83146113bb5760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e63682900000000000060648201526084016102bd565b9650610e4795505050505050565b60008584815181106113dd576113dd612f28565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061140857611408612f28565b6020026020010151905061141b81611bef565b9550611428600186612f3e565b9450505061181b565b6002816020015151036117ad57600061144982611c14565b905060008160008151811061146057611460612f28565b016020015160f81c90506000611477600283612f8c565b611482906002612fae565b90506000611493848360ff16611c38565b905060006114a18a89611c38565b905060006114af8383611c6e565b9050808351146115275760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b657900000000000060648201526084016102bd565b60ff85166002148061153c575060ff85166003145b156116e257808251146115b75760405162461bcd60e51b815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e64657200000060648201526084016102bd565b60006115d388602001516001815181106112b3576112b3612f28565b9050600081511161164c5760405162461bcd60e51b815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c656166290000000000000060648201526084016102bd565b60018d5161165a9190612de0565b89146116ce5760405162461bcd60e51b815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c65616629000000000000000060648201526084016102bd565b9c50610e479b505050505050505050505050565b60ff851615806116f5575060ff85166001145b1561173457611721876020015160018151811061171457611714612f28565b6020026020010151611bef565b995061172d818a612f3e565b98506117a2565b60405162461bcd60e51b815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e20707265666978000000000000000000000000000060648201526084016102bd565b50505050505061181b565b60405162461bcd60e51b815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f646500000000000000000000000000000000000000000000000060648201526084016102bd565b508061182681612f51565b915050611018565b5060405162461bcd60e51b815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e747300000000000000000000000000000000000000000000000000000060648201526084016102bd565b6040805180820190915260008082526020820152600082511161193b5760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f206265606482015269206465636f6461626c6560b01b608482015260a4016102bd565b50604080518082019091528151815260209182019181019190915290565b6060600080600061196985611d05565b91945092509050600081600181111561198457611984612fc7565b146119f75760405162461bcd60e51b815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d0000000000000060648201526084016102bd565b611a018284612f3e565b855114611a765760405162461bcd60e51b815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e64657200000000000000000000000060648201526084016102bd565b611a85856020015184846125c7565b95945050505050565b606061065f8484600085612668565b805160609060008167ffffffffffffffff811115611abd57611abd612e0c565b604051908082528060200260200182016040528015611b0257816020015b6040805180820190915260608082526020820152815260200190600190039081611adb5790505b50905060005b82811015611b84576040518060400160405280868381518110611b2d57611b2d612f28565b60200260200101518152602001611b5c878481518110611b4f57611b4f612f28565b602002602001015161274f565b815250828281518110611b7157611b71612f28565b6020908102919091010152600101611b08565b509392505050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015611be4578060011b82018184015160001a8060041c8253600f811660018301535050600101611bb6565b509295945050505050565b60606020826000015110611c0b57611c0682611959565b610e61565b610e6182612762565b6060610e61611c3383602001516000815181106112b3576112b3612f28565b611b8c565b606082518210611c575750604080516020810190915260008152610e61565b610e478383848651611c699190612de0565b612778565b60008060008351855110611c83578351611c86565b84515b90505b8082108015611cf55750838281518110611ca557611ca5612f28565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858381518110611ce457611ce4612f28565b01602001516001600160f81b031916145b15611b8457816001019150611c89565b600080600080846000015111611d965760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f206265606482015269206465636f6461626c6560b01b608482015260a4016102bd565b6020840151805160001a607f8111611dbb5760006001600094509450945050506125c0565b60b78111611f65576000611dd0608083612de0565b905080876000015111611e715760405162461bcd60e51b815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a4016102bd565b6001838101516001600160f81b0319169082141580611eba57507f80000000000000000000000000000000000000000000000000000000000000006001600160f81b0319821610155b611f525760405162461bcd60e51b815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a4016102bd565b50600195509350600092506125c0915050565b60bf8111612233576000611f7a60b783612de0565b90508087600001511161201b5760405162461bcd60e51b815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a4016102bd565b60018301516001600160f81b03191660008190036120c75760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a4016102bd565b600184015160088302610100031c603781116121715760405162461bcd60e51b815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a4016102bd565b61217b8184612f3e565b8951116122165760405162461bcd60e51b815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a4016102bd565b612221836001612f3e565b97509550600094506125c09350505050565b60f781116122fa57600061224860c083612de0565b9050808760000151116122e95760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a4016102bd565b6001955093508492506125c0915050565b600061230760f783612de0565b9050808760000151116123a85760405162461bcd60e51b815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a4016102bd565b60018301516001600160f81b03191660008190036124545760405162461bcd60e51b815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a4016102bd565b600184015160088302610100031c603781116124fe5760405162461bcd60e51b815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a4016102bd565b6125088184612f3e565b8951116125a35760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a4016102bd565b6125ae836001612f3e565b97509550600194506125c09350505050565b9193909250565b606060008267ffffffffffffffff8111156125e4576125e4612e0c565b6040519080825280601f01601f19166020018201604052801561260e576020820181803683370190505b50905082600003612620579050610e47565b600061262c8587612f3e565b90506020820160005b8581101561264d578281015182820152602001612635565b8581111561265c576000868301525b50919695505050505050565b6060824710156126e05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016102bd565b600080866001600160a01b031685876040516126fc9190613001565b60006040518083038185875af1925050503d8060008114612739576040519150601f19603f3d011682016040523d82523d6000602084013e61273e565b606091505b509150915061065a878383876128e4565b6060610e6161275d8361189d565b61295d565b6060610e618260200151600084600001516125c7565b60608182601f0110156127cd5760405162461bcd60e51b815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016102bd565b82828401101561281f5760405162461bcd60e51b815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016102bd565b818301845110156128725760405162461bcd60e51b815260206004820152601160248201527f736c6963655f6f75744f66426f756e647300000000000000000000000000000060448201526064016102bd565b60608215801561289157604051915060008252602082016040526128db565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156128ca5780518352602092830192016128b2565b5050858452601f01601f1916604052505b50949350505050565b6060831561295357825160000361294c576001600160a01b0385163b61294c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102bd565b508161065f565b61065f8383612b8d565b6060600080600061296d85611d05565b91945092509050600181600181111561298857612988612fc7565b146129fb5760405162461bcd60e51b815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d000000000000000060648201526084016102bd565b8451612a078385612f3e565b14612a7a5760405162461bcd60e51b815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e646572000000000000000000000000000060648201526084016102bd565b6040805160208082526104208201909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081612a935790505090506000845b8751811015612b8157600080612b066040518060400160405280858d60000151612aea9190612de0565b8152602001858d60200151612aff9190612f3e565b9052611d05565b509150915060405180604001604052808383612b229190612f3e565b8152602001848c60200151612b379190612f3e565b815250858581518110612b4c57612b4c612f28565b6020908102919091010152612b62600185612f3e565b9350612b6e8183612f3e565b612b789084612f3e565b92505050612ac0565b50815295945050505050565b815115612b9d5781518083602001fd5b8060405162461bcd60e51b81526004016102bd919061301d565b60008083601f840112612bc957600080fd5b50813567ffffffffffffffff811115612be157600080fd5b6020830191508360208260051b8501011115612bfc57600080fd5b9250929050565b600080600060408486031215612c1857600080fd5b83359250602084013567ffffffffffffffff811115612c3657600080fd5b612c4286828701612bb7565b9497909650939450505050565b80356001600160a01b0381168114612c6657600080fd5b919050565b60008060408385031215612c7e57600080fd5b612c8783612c4f565b9150612c9560208401612c4f565b90509250929050565b600060208284031215612cb057600080fd5b610e4782612c4f565b60008060008060608587031215612ccf57600080fd5b84359350612cdf60208601612c4f565b9250604085013567ffffffffffffffff811115612cfb57600080fd5b612d0787828801612bb7565b95989497509550505050565b600080600080600060a08688031215612d2b57600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060408385031215612d6157600080fd5b50508035926020909101359150565b600060208284031215612d8257600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e6157610e61612d89565b634e487b7160e01b600052601260045260246000fd5b600082612ddb57612ddb612db6565b500490565b81810381811115610e6157610e61612d89565b600060208284031215612e0557600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612e4b57612e4b612e0c565b604052919050565b600067ffffffffffffffff80841115612e6e57612e6e612e0c565b8360051b6020612e7f818301612e22565b868152918501918181019036841115612e9757600080fd5b865b84811015612f1c57803586811115612eb15760008081fd5b8801601f3681830112612ec45760008081fd5b813588811115612ed657612ed6612e0c565b612ee7818301601f19168801612e22565b91508082523687828501011115612efe5760008081fd5b80878401888401376000908201870152845250918301918301612e99565b50979650505050505050565b634e487b7160e01b600052603260045260246000fd5b80820180821115610e6157610e61612d89565b600060018201612f6357612f63612d89565b5060010190565b600060208284031215612f7c57600080fd5b81518015158114610e4757600080fd5b600060ff831680612f9f57612f9f612db6565b8060ff84160691505092915050565b60ff8281168282160390811115610e6157610e61612d89565b634e487b7160e01b600052602160045260246000fd5b60005b83811015612ff8578181015183820152602001612fe0565b50506000910152565b60008251613013818460208701612fdd565b9190910192915050565b602081526000825180602084015261303c816040850160208701612fdd565b601f01601f1916919091016040019291505056fea2646970667358221220ef586eb6a714f1d80c54375ad6c7029882b499d015fab7a74b47a02e7dd863e864736f6c63430008130033", + "devdoc": { + "kind": "dev", + "methods": { + "addReward(uint256,bytes32,uint256,uint256,uint256)": { + "params": { + "amount": "The amount of reward tokens to deposit", + "blockNumber": "The block number for the Reward", + "merkleRoot": "The merkle root of the distribution tree", + "totalStakedBalance": "Total staked balance of the merkleRoot (computed off-chain)", + "withdrawUnlockTime": "The timestamp after which withdrawals by owner are allowed" + } + }, + "claim(uint256,bytes[])": { + "details": "Checks proofs and claims tracking before transferring rewardTokens", + "params": { + "blockNumber": "The block number for the Reward", + "proof": "The merkle proof for the claim" + } + }, + "constructor": { + "params": { + "_rewardToken": "The reward token to be distributed" + } + }, + "isClaimable(uint256,address,bytes[])": { + "params": { + "account": "The address of the account claiming", + "blockNumber": "The block number for the Reward", + "proof": "The merkle proof for the claim" + }, + "returns": { + "_0": "A bool indicating if the claim is valid and claimable" + } + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "setDelegator(address,address)": { + "params": { + "_delegator": "The address that sould claim on behalf of the owner", + "_recipient": "original eligible recipient address" + } + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + }, + "withdrawFunds(uint256,uint256)": { + "params": { + "amount": "The amount to withdraw", + "blockNumber": "The block number for the Reward" + } + } + }, + "title": "Sonne Finance Merkle tree-based rewards distributor", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "addReward(uint256,bytes32,uint256,uint256,uint256)": { + "notice": "Creates a new Reward struct for a rewards distribution" + }, + "claim(uint256,bytes[])": { + "notice": "Claims the specified amount for an account if valid" + }, + "constructor": { + "notice": "Contract constructor to initialize rewardToken" + }, + "isClaimable(uint256,address,bytes[])": { + "notice": "Checks if a claim is valid and claimable" + }, + "setDelegator(address,address)": { + "notice": "Sets a delegator address for a given recipient" + }, + "withdrawFunds(uint256,uint256)": { + "notice": "Allows to withdraw available funds to owner after unlock time" + } + }, + "notice": "Contract to distribute rewards on BASE network to Sonne Finance Optimism stakers", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 1420, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "_status", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 1304, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "_owner", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 3325, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "rewards", + "offset": 0, + "slot": "2", + "type": "t_array(t_uint256)dyn_storage" + }, + { + "astId": 3330, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "Rewards", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Reward)3319_storage)" + }, + { + "astId": 3334, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "delegatorAddresses", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_address,t_address)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)dyn_storage": { + "base": "t_uint256", + "encoding": "dynamic_array", + "label": "uint256[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_address)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_bytes32,t_bool)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_uint256,t_struct(Reward)3319_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct SonneMerkleDistributor.Reward)", + "numberOfBytes": "32", + "value": "t_struct(Reward)3319_storage" + }, + "t_struct(Reward)3319_storage": { + "encoding": "inplace", + "label": "struct SonneMerkleDistributor.Reward", + "members": [ + { + "astId": 3308, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "balance", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 3310, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "merkleRoot", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + }, + { + "astId": 3312, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "withdrawUnlockTime", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 3314, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "ratio", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 3318, + "contract": "contracts/SonneMerkleDistributor.sol:SonneMerkleDistributor", + "label": "leafClaimed", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_bytes32,t_bool)" + } + ], + "numberOfBytes": "160" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/crosschain-rewards/deployments/base/solcInputs/30087f7fee47449a419e52a71b53a636.json b/crosschain-rewards/deployments/base/solcInputs/30087f7fee47449a419e52a71b53a636.json new file mode 100644 index 0000000..b94f3b9 --- /dev/null +++ b/crosschain-rewards/deployments/base/solcInputs/30087f7fee47449a419e52a71b53a636.json @@ -0,0 +1,95 @@ +{ + "language": "Solidity", + "sources": { + "@eth-optimism/contracts-bedrock/contracts/libraries/Bytes.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title Bytes\n/// @notice Bytes is a library for manipulating byte arrays.\nlibrary Bytes {\n /// @custom:attribution https://github.com/GNSPS/solidity-bytes-utils\n /// @notice Slices a byte array with a given starting index and length. Returns a new byte array\n /// as opposed to a pointer to the original array. Will throw if trying to slice more\n /// bytes than exist in the array.\n /// @param _bytes Byte array to slice.\n /// @param _start Starting index of the slice.\n /// @param _length Length of the slice.\n /// @return Slice of the input byte array.\n function slice(\n bytes memory _bytes,\n uint256 _start,\n uint256 _length\n ) internal pure returns (bytes memory) {\n unchecked {\n require(_length + 31 >= _length, \"slice_overflow\");\n require(_start + _length >= _start, \"slice_overflow\");\n require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n }\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n\n //zero out the 32 bytes slice we are about to return\n //we need to do it because Solidity does not garbage collect\n mstore(tempBytes, 0)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n\n /// @notice Slices a byte array with a given starting index up to the end of the original byte\n /// array. Returns a new array rathern than a pointer to the original.\n /// @param _bytes Byte array to slice.\n /// @param _start Starting index of the slice.\n /// @return Slice of the input byte array.\n function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) {\n if (_start >= _bytes.length) {\n return bytes(\"\");\n }\n return slice(_bytes, _start, _bytes.length - _start);\n }\n\n /// @notice Converts a byte array into a nibble array by splitting each byte into two nibbles.\n /// Resulting nibble array will be exactly twice as long as the input byte array.\n /// @param _bytes Input byte array to convert.\n /// @return Resulting nibble array.\n function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) {\n bytes memory _nibbles;\n assembly {\n // Grab a free memory offset for the new array\n _nibbles := mload(0x40)\n\n // Load the length of the passed bytes array from memory\n let bytesLength := mload(_bytes)\n\n // Calculate the length of the new nibble array\n // This is the length of the input array times 2\n let nibblesLength := shl(0x01, bytesLength)\n\n // Update the free memory pointer to allocate memory for the new array.\n // To do this, we add the length of the new array + 32 bytes for the array length\n // rounded up to the nearest 32 byte boundary to the current free memory pointer.\n mstore(0x40, add(_nibbles, and(not(0x1F), add(nibblesLength, 0x3F))))\n\n // Store the length of the new array in memory\n mstore(_nibbles, nibblesLength)\n\n // Store the memory offset of the _bytes array's contents on the stack\n let bytesStart := add(_bytes, 0x20)\n\n // Store the memory offset of the nibbles array's contents on the stack\n let nibblesStart := add(_nibbles, 0x20)\n\n // Loop through each byte in the input array\n for {\n let i := 0x00\n } lt(i, bytesLength) {\n i := add(i, 0x01)\n } {\n // Get the starting offset of the next 2 bytes in the nibbles array\n let offset := add(nibblesStart, shl(0x01, i))\n // Load the byte at the current index within the `_bytes` array\n let b := byte(0x00, mload(add(bytesStart, i)))\n\n // Pull out the first nibble and store it in the new array\n mstore8(offset, shr(0x04, b))\n // Pull out the second nibble and store it in the new array\n mstore8(add(offset, 0x01), and(b, 0x0F))\n }\n }\n return _nibbles;\n }\n\n /// @notice Compares two byte arrays by comparing their keccak256 hashes.\n /// @param _bytes First byte array to compare.\n /// @param _other Second byte array to compare.\n /// @return True if the two byte arrays are equal, false otherwise.\n function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) {\n return keccak256(_bytes) == keccak256(_other);\n }\n}\n" + }, + "@eth-optimism/contracts-bedrock/contracts/libraries/rlp/RLPReader.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\n/**\n * @custom:attribution https://github.com/hamdiallam/Solidity-RLP\n * @title RLPReader\n * @notice RLPReader is a library for parsing RLP-encoded byte arrays into Solidity types. Adapted\n * from Solidity-RLP (https://github.com/hamdiallam/Solidity-RLP) by Hamdi Allam with\n * various tweaks to improve readability.\n */\nlibrary RLPReader {\n /**\n * Custom pointer type to avoid confusion between pointers and uint256s.\n */\n type MemoryPointer is uint256;\n\n /**\n * @notice RLP item types.\n *\n * @custom:value DATA_ITEM Represents an RLP data item (NOT a list).\n * @custom:value LIST_ITEM Represents an RLP list item.\n */\n enum RLPItemType {\n DATA_ITEM,\n LIST_ITEM\n }\n\n /**\n * @notice Struct representing an RLP item.\n *\n * @custom:field length Length of the RLP item.\n * @custom:field ptr Pointer to the RLP item in memory.\n */\n struct RLPItem {\n uint256 length;\n MemoryPointer ptr;\n }\n\n /**\n * @notice Max list length that this library will accept.\n */\n uint256 internal constant MAX_LIST_LENGTH = 32;\n\n /**\n * @notice Converts bytes to a reference to memory position and length.\n *\n * @param _in Input bytes to convert.\n *\n * @return Output memory reference.\n */\n function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory) {\n // Empty arrays are not RLP items.\n require(\n _in.length > 0,\n \"RLPReader: length of an RLP item must be greater than zero to be decodable\"\n );\n\n MemoryPointer ptr;\n assembly {\n ptr := add(_in, 32)\n }\n\n return RLPItem({ length: _in.length, ptr: ptr });\n }\n\n /**\n * @notice Reads an RLP list value into a list of RLP items.\n *\n * @param _in RLP list value.\n *\n * @return Decoded RLP list items.\n */\n function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) {\n (uint256 listOffset, uint256 listLength, RLPItemType itemType) = _decodeLength(_in);\n\n require(\n itemType == RLPItemType.LIST_ITEM,\n \"RLPReader: decoded item type for list is not a list item\"\n );\n\n require(\n listOffset + listLength == _in.length,\n \"RLPReader: list item has an invalid data remainder\"\n );\n\n // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by\n // writing to the length. Since we can't know the number of RLP items without looping over\n // the entire input, we'd have to loop twice to accurately size this array. It's easier to\n // simply set a reasonable maximum list length and decrease the size before we finish.\n RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH);\n\n uint256 itemCount = 0;\n uint256 offset = listOffset;\n while (offset < _in.length) {\n (uint256 itemOffset, uint256 itemLength, ) = _decodeLength(\n RLPItem({\n length: _in.length - offset,\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\n })\n );\n\n // We don't need to check itemCount < out.length explicitly because Solidity already\n // handles this check on our behalf, we'd just be wasting gas.\n out[itemCount] = RLPItem({\n length: itemLength + itemOffset,\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\n });\n\n itemCount += 1;\n offset += itemOffset + itemLength;\n }\n\n // Decrease the array size to match the actual item count.\n assembly {\n mstore(out, itemCount)\n }\n\n return out;\n }\n\n /**\n * @notice Reads an RLP list value into a list of RLP items.\n *\n * @param _in RLP list value.\n *\n * @return Decoded RLP list items.\n */\n function readList(bytes memory _in) internal pure returns (RLPItem[] memory) {\n return readList(toRLPItem(_in));\n }\n\n /**\n * @notice Reads an RLP bytes value into bytes.\n *\n * @param _in RLP bytes value.\n *\n * @return Decoded bytes.\n */\n function readBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);\n\n require(\n itemType == RLPItemType.DATA_ITEM,\n \"RLPReader: decoded item type for bytes is not a data item\"\n );\n\n require(\n _in.length == itemOffset + itemLength,\n \"RLPReader: bytes value contains an invalid remainder\"\n );\n\n return _copy(_in.ptr, itemOffset, itemLength);\n }\n\n /**\n * @notice Reads an RLP bytes value into bytes.\n *\n * @param _in RLP bytes value.\n *\n * @return Decoded bytes.\n */\n function readBytes(bytes memory _in) internal pure returns (bytes memory) {\n return readBytes(toRLPItem(_in));\n }\n\n /**\n * @notice Reads the raw bytes of an RLP item.\n *\n * @param _in RLP item to read.\n *\n * @return Raw RLP bytes.\n */\n function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n return _copy(_in.ptr, 0, _in.length);\n }\n\n /**\n * @notice Decodes the length of an RLP item.\n *\n * @param _in RLP item to decode.\n *\n * @return Offset of the encoded data.\n * @return Length of the encoded data.\n * @return RLP item type (LIST_ITEM or DATA_ITEM).\n */\n function _decodeLength(RLPItem memory _in)\n private\n pure\n returns (\n uint256,\n uint256,\n RLPItemType\n )\n {\n // Short-circuit if there's nothing to decode, note that we perform this check when\n // the user creates an RLP item via toRLPItem, but it's always possible for them to bypass\n // that function and create an RLP item directly. So we need to check this anyway.\n require(\n _in.length > 0,\n \"RLPReader: length of an RLP item must be greater than zero to be decodable\"\n );\n\n MemoryPointer ptr = _in.ptr;\n uint256 prefix;\n assembly {\n prefix := byte(0, mload(ptr))\n }\n\n if (prefix <= 0x7f) {\n // Single byte.\n return (0, 1, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xb7) {\n // Short string.\n\n // slither-disable-next-line variable-scope\n uint256 strLen = prefix - 0x80;\n\n require(\n _in.length > strLen,\n \"RLPReader: length of content must be greater than string length (short string)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n strLen != 1 || firstByteOfContent >= 0x80,\n \"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\"\n );\n\n return (1, strLen, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xbf) {\n // Long string.\n uint256 lenOfStrLen = prefix - 0xb7;\n\n require(\n _in.length > lenOfStrLen,\n \"RLPReader: length of content must be > than length of string length (long string)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n firstByteOfContent != 0x00,\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n\n uint256 strLen;\n assembly {\n strLen := shr(sub(256, mul(8, lenOfStrLen)), mload(add(ptr, 1)))\n }\n\n require(\n strLen > 55,\n \"RLPReader: length of content must be greater than 55 bytes (long string)\"\n );\n\n require(\n _in.length > lenOfStrLen + strLen,\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n\n return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xf7) {\n // Short list.\n // slither-disable-next-line variable-scope\n uint256 listLen = prefix - 0xc0;\n\n require(\n _in.length > listLen,\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n\n return (1, listLen, RLPItemType.LIST_ITEM);\n } else {\n // Long list.\n uint256 lenOfListLen = prefix - 0xf7;\n\n require(\n _in.length > lenOfListLen,\n \"RLPReader: length of content must be > than length of list length (long list)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n firstByteOfContent != 0x00,\n \"RLPReader: length of content must not have any leading zeros (long list)\"\n );\n\n uint256 listLen;\n assembly {\n listLen := shr(sub(256, mul(8, lenOfListLen)), mload(add(ptr, 1)))\n }\n\n require(\n listLen > 55,\n \"RLPReader: length of content must be greater than 55 bytes (long list)\"\n );\n\n require(\n _in.length > lenOfListLen + listLen,\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n\n return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM);\n }\n }\n\n /**\n * @notice Copies the bytes from a memory location.\n *\n * @param _src Pointer to the location to read from.\n * @param _offset Offset to start reading from.\n * @param _length Number of bytes to read.\n *\n * @return Copied bytes.\n */\n function _copy(\n MemoryPointer _src,\n uint256 _offset,\n uint256 _length\n ) private pure returns (bytes memory) {\n bytes memory out = new bytes(_length);\n if (_length == 0) {\n return out;\n }\n\n // Mostly based on Solidity's copy_memory_to_memory:\n // solhint-disable max-line-length\n // https://github.com/ethereum/solidity/blob/34dd30d71b4da730488be72ff6af7083cf2a91f6/libsolidity/codegen/YulUtilFunctions.cpp#L102-L114\n uint256 src = MemoryPointer.unwrap(_src) + _offset;\n assembly {\n let dest := add(out, 32)\n let i := 0\n for {\n\n } lt(i, _length) {\n i := add(i, 32)\n } {\n mstore(add(dest, i), mload(add(src, i)))\n }\n\n if gt(i, _length) {\n mstore(add(dest, _length), 0)\n }\n }\n\n return out;\n }\n}\n" + }, + "@eth-optimism/contracts-bedrock/contracts/libraries/trie/MerkleTrie.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Bytes } from \"../Bytes.sol\";\nimport { RLPReader } from \"../rlp/RLPReader.sol\";\n\n/**\n * @title MerkleTrie\n * @notice MerkleTrie is a small library for verifying standard Ethereum Merkle-Patricia trie\n * inclusion proofs. By default, this library assumes a hexary trie. One can change the\n * trie radix constant to support other trie radixes.\n */\nlibrary MerkleTrie {\n /**\n * @notice Struct representing a node in the trie.\n *\n * @custom:field encoded The RLP-encoded node.\n * @custom:field decoded The RLP-decoded node.\n */\n struct TrieNode {\n bytes encoded;\n RLPReader.RLPItem[] decoded;\n }\n\n /**\n * @notice Determines the number of elements per branch node.\n */\n uint256 internal constant TREE_RADIX = 16;\n\n /**\n * @notice Branch nodes have TREE_RADIX elements and one value element.\n */\n uint256 internal constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;\n\n /**\n * @notice Leaf nodes and extension nodes have two elements, a `path` and a `value`.\n */\n uint256 internal constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;\n\n /**\n * @notice Prefix for even-nibbled extension node paths.\n */\n uint8 internal constant PREFIX_EXTENSION_EVEN = 0;\n\n /**\n * @notice Prefix for odd-nibbled extension node paths.\n */\n uint8 internal constant PREFIX_EXTENSION_ODD = 1;\n\n /**\n * @notice Prefix for even-nibbled leaf node paths.\n */\n uint8 internal constant PREFIX_LEAF_EVEN = 2;\n\n /**\n * @notice Prefix for odd-nibbled leaf node paths.\n */\n uint8 internal constant PREFIX_LEAF_ODD = 3;\n\n /**\n * @notice Verifies a proof that a given key/value pair is present in the trie.\n *\n * @param _key Key of the node to search for, as a hex string.\n * @param _value Value of the node to search for, as a hex string.\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\n * nodes that make a path down to the target node.\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\n * correctly constructed.\n *\n * @return Whether or not the proof is valid.\n */\n function verifyInclusionProof(\n bytes memory _key,\n bytes memory _value,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bool) {\n return Bytes.equal(_value, get(_key, _proof, _root));\n }\n\n /**\n * @notice Retrieves the value associated with a given key.\n *\n * @param _key Key to search for, as hex bytes.\n * @param _proof Merkle trie inclusion proof for the key.\n * @param _root Known root of the Merkle trie.\n *\n * @return Value of the key if it exists.\n */\n function get(\n bytes memory _key,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n require(_key.length > 0, \"MerkleTrie: empty key\");\n\n TrieNode[] memory proof = _parseProof(_proof);\n bytes memory key = Bytes.toNibbles(_key);\n bytes memory currentNodeID = abi.encodePacked(_root);\n uint256 currentKeyIndex = 0;\n\n // Proof is top-down, so we start at the first element (root).\n for (uint256 i = 0; i < proof.length; i++) {\n TrieNode memory currentNode = proof[i];\n\n // Key index should never exceed total key length or we'll be out of bounds.\n require(\n currentKeyIndex <= key.length,\n \"MerkleTrie: key index exceeds total key length\"\n );\n\n if (currentKeyIndex == 0) {\n // First proof element is always the root node.\n require(\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\n \"MerkleTrie: invalid root hash\"\n );\n } else if (currentNode.encoded.length >= 32) {\n // Nodes 32 bytes or larger are hashed inside branch nodes.\n require(\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\n \"MerkleTrie: invalid large internal hash\"\n );\n } else {\n // Nodes smaller than 32 bytes aren't hashed.\n require(\n Bytes.equal(currentNode.encoded, currentNodeID),\n \"MerkleTrie: invalid internal node hash\"\n );\n }\n\n if (currentNode.decoded.length == BRANCH_NODE_LENGTH) {\n if (currentKeyIndex == key.length) {\n // Value is the last element of the decoded list (for branch nodes). There's\n // some ambiguity in the Merkle trie specification because bytes(0) is a\n // valid value to place into the trie, but for branch nodes bytes(0) can exist\n // even when the value wasn't explicitly placed there. Geth treats a value of\n // bytes(0) as \"key does not exist\" and so we do the same.\n bytes memory value = RLPReader.readBytes(currentNode.decoded[TREE_RADIX]);\n require(\n value.length > 0,\n \"MerkleTrie: value length must be greater than zero (branch)\"\n );\n\n // Extra proof elements are not allowed.\n require(\n i == proof.length - 1,\n \"MerkleTrie: value node must be last node in proof (branch)\"\n );\n\n return value;\n } else {\n // We're not at the end of the key yet.\n // Figure out what the next node ID should be and continue.\n uint8 branchKey = uint8(key[currentKeyIndex]);\n RLPReader.RLPItem memory nextNode = currentNode.decoded[branchKey];\n currentNodeID = _getNodeID(nextNode);\n currentKeyIndex += 1;\n }\n } else if (currentNode.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) {\n bytes memory path = _getNodePath(currentNode);\n uint8 prefix = uint8(path[0]);\n uint8 offset = 2 - (prefix % 2);\n bytes memory pathRemainder = Bytes.slice(path, offset);\n bytes memory keyRemainder = Bytes.slice(key, currentKeyIndex);\n uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder);\n\n // Whether this is a leaf node or an extension node, the path remainder MUST be a\n // prefix of the key remainder (or be equal to the key remainder) or the proof is\n // considered invalid.\n require(\n pathRemainder.length == sharedNibbleLength,\n \"MerkleTrie: path remainder must share all nibbles with key\"\n );\n\n if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) {\n // Prefix of 2 or 3 means this is a leaf node. For the leaf node to be valid,\n // the key remainder must be exactly equal to the path remainder. We already\n // did the necessary byte comparison, so it's more efficient here to check that\n // the key remainder length equals the shared nibble length, which implies\n // equality with the path remainder (since we already did the same check with\n // the path remainder and the shared nibble length).\n require(\n keyRemainder.length == sharedNibbleLength,\n \"MerkleTrie: key remainder must be identical to path remainder\"\n );\n\n // Our Merkle Trie is designed specifically for the purposes of the Ethereum\n // state trie. Empty values are not allowed in the state trie, so we can safely\n // say that if the value is empty, the key should not exist and the proof is\n // invalid.\n bytes memory value = RLPReader.readBytes(currentNode.decoded[1]);\n require(\n value.length > 0,\n \"MerkleTrie: value length must be greater than zero (leaf)\"\n );\n\n // Extra proof elements are not allowed.\n require(\n i == proof.length - 1,\n \"MerkleTrie: value node must be last node in proof (leaf)\"\n );\n\n return value;\n } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {\n // Prefix of 0 or 1 means this is an extension node. We move onto the next node\n // in the proof and increment the key index by the length of the path remainder\n // which is equal to the shared nibble length.\n currentNodeID = _getNodeID(currentNode.decoded[1]);\n currentKeyIndex += sharedNibbleLength;\n } else {\n revert(\"MerkleTrie: received a node with an unknown prefix\");\n }\n } else {\n revert(\"MerkleTrie: received an unparseable node\");\n }\n }\n\n revert(\"MerkleTrie: ran out of proof elements\");\n }\n\n /**\n * @notice Parses an array of proof elements into a new array that contains both the original\n * encoded element and the RLP-decoded element.\n *\n * @param _proof Array of proof elements to parse.\n *\n * @return Proof parsed into easily accessible structs.\n */\n function _parseProof(bytes[] memory _proof) private pure returns (TrieNode[] memory) {\n uint256 length = _proof.length;\n TrieNode[] memory proof = new TrieNode[](length);\n for (uint256 i = 0; i < length; ) {\n proof[i] = TrieNode({ encoded: _proof[i], decoded: RLPReader.readList(_proof[i]) });\n unchecked {\n ++i;\n }\n }\n return proof;\n }\n\n /**\n * @notice Picks out the ID for a node. Node ID is referred to as the \"hash\" within the\n * specification, but nodes < 32 bytes are not actually hashed.\n *\n * @param _node Node to pull an ID for.\n *\n * @return ID for the node, depending on the size of its contents.\n */\n function _getNodeID(RLPReader.RLPItem memory _node) private pure returns (bytes memory) {\n return _node.length < 32 ? RLPReader.readRawBytes(_node) : RLPReader.readBytes(_node);\n }\n\n /**\n * @notice Gets the path for a leaf or extension node.\n *\n * @param _node Node to get a path for.\n *\n * @return Node path, converted to an array of nibbles.\n */\n function _getNodePath(TrieNode memory _node) private pure returns (bytes memory) {\n return Bytes.toNibbles(RLPReader.readBytes(_node.decoded[0]));\n }\n\n /**\n * @notice Utility; determines the number of nibbles shared between two nibble arrays.\n *\n * @param _a First nibble array.\n * @param _b Second nibble array.\n *\n * @return Number of shared nibbles.\n */\n function _getSharedNibbleLength(bytes memory _a, bytes memory _b)\n private\n pure\n returns (uint256)\n {\n uint256 shared;\n uint256 max = (_a.length < _b.length) ? _a.length : _b.length;\n for (; shared < max && _a[shared] == _b[shared]; ) {\n unchecked {\n ++shared;\n }\n }\n return shared;\n }\n}\n" + }, + "@eth-optimism/contracts-bedrock/contracts/libraries/trie/SecureMerkleTrie.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/* Library Imports */\nimport { MerkleTrie } from \"./MerkleTrie.sol\";\n\n/**\n * @title SecureMerkleTrie\n * @notice SecureMerkleTrie is a thin wrapper around the MerkleTrie library that hashes the input\n * keys. Ethereum's state trie hashes input keys before storing them.\n */\nlibrary SecureMerkleTrie {\n /**\n * @notice Verifies a proof that a given key/value pair is present in the Merkle trie.\n *\n * @param _key Key of the node to search for, as a hex string.\n * @param _value Value of the node to search for, as a hex string.\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\n * nodes that make a path down to the target node.\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\n * correctly constructed.\n *\n * @return Whether or not the proof is valid.\n */\n function verifyInclusionProof(\n bytes memory _key,\n bytes memory _value,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bool) {\n bytes memory key = _getSecureKey(_key);\n return MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);\n }\n\n /**\n * @notice Retrieves the value associated with a given key.\n *\n * @param _key Key to search for, as hex bytes.\n * @param _proof Merkle trie inclusion proof for the key.\n * @param _root Known root of the Merkle trie.\n *\n * @return Value of the key if it exists.\n */\n function get(\n bytes memory _key,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n bytes memory key = _getSecureKey(_key);\n return MerkleTrie.get(key, _proof, _root);\n }\n\n /**\n * @notice Computes the hashed version of the input key.\n *\n * @param _key Key to hash.\n *\n * @return Hashed version of the key.\n */\n function _getSecureKey(bytes memory _key) private pure returns (bytes memory) {\n return abi.encodePacked(keccak256(_key));\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling 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/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (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 _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\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 /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\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 * 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 default value returned by this function, unless\n * it's 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(address from, address to, uint256 amount) 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(address from, address to, uint256 amount) 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 // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\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 unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\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 // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\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(address owner, address spender, uint256 amount) 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(address owner, address spender, uint256 amount) 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(address from, address to, uint256 amount) 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(address from, address to, uint256 amount) internal virtual {}\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/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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 * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, \"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(address target, bytes memory data, uint256 value) 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 (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or 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 _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\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" + }, + "@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/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "contracts/Delegator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.19;\n\ncontract Delegate {\n\n mapping(address => address) public delegates;\n\n event DelegateChanged(address indexed addr, address newDelegate);\n\n function setDelegate(address delegate) public {\n delegates[msg.sender] = delegate;\n emit DelegateChanged(msg.sender, delegate);\n }\n\n function getDelegate(address addr) public view returns (address) {\n return delegates[addr];\n }\n}" + }, + "contracts/interfaces/IERC20WithPermit.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.19;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IERC20WithPermit is IERC20 {\n function permit(\n address,\n address,\n uint256,\n uint256,\n uint8,\n bytes32,\n bytes32\n ) external;\n}" + }, + "contracts/interfaces/ISonneMerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.19;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ninterface ISonneMerkleDistributor {\n event NewMerkle(\n address indexed creator,\n address indexed rewardToken,\n uint256 amount,\n bytes32 indexed merkleRoot,\n uint256 blockNr,\n uint256 withdrawUnlockTime\n );\n event MerkleFundUpdate(\n address indexed funder,\n bytes32 indexed merkleRoot,\n uint256 blockNr,\n uint256 amount,\n bool withdrawal\n );\n event MerkleClaim(address indexed claimer, address indexed rewardToken, uint256 indexed blockNr, uint256 amount);\n\n function rewardToken() external view returns (IERC20);\n\n function Rewards(\n uint256 blockNumber\n ) external view returns (uint256 balance, bytes32 merkleRoot, uint256 withdrawUnlockTime, uint256 ratio);\n\n function delegatorAddresses(address _delegator) external view returns (address originalRecipient);\n\n function setDelegator(address _recipient, address _delegator) external;\n\n function addReward(\n uint256 amount,\n bytes32 merkleRoot,\n uint256 blockNumber,\n uint256 withdrawUnlockTime,\n uint256 totalStakedBalance\n ) external;\n\n function withdrawFunds(uint256 blockNumber, uint256 amount) external;\n\n function claim(uint256 blockNumber, bytes[] calldata proof) external;\n\n function isClaimable(uint256 blockNumber, address account, bytes[] calldata proof) external view returns (bool);\n}\n" + }, + "contracts/mocks/ERC20Mock.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.19;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n// mock class using ERC20\ncontract ERC20Mock is ERC20 {\n constructor(\n string memory name,\n string memory symbol,\n address initialAccount,\n uint256 initialBalance\n ) public payable ERC20(name, symbol) {\n _mint(initialAccount, initialBalance);\n }\n\n function mint(address account, uint256 amount) public {\n _mint(account, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n }\n\n function transferInternal(\n address from,\n address to,\n uint256 value\n ) public {\n _transfer(from, to, value);\n }\n\n function approveInternal(\n address owner,\n address spender,\n uint256 value\n ) public {\n _approve(owner, spender, value);\n }\n}" + }, + "contracts/mocks/ERC20WithPermitMock.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.19;\n\nimport \"../interfaces/IERC20WithPermit.sol\";\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\ncontract ERC20WithPermitMock is IERC20WithPermit {\n using SafeMath for uint256;\n\n string public constant name = \"ERC20WithPermit\";\n string public constant symbol = \"ERC20WP\";\n uint8 public constant decimals = 18;\n uint256 public override totalSupply;\n mapping(address => uint256) public override balanceOf;\n mapping(address => mapping(address => uint256)) public override allowance;\n\n bytes32 public DOMAIN_SEPARATOR;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH =\n 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint256) public nonces;\n\n constructor() {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n ),\n keccak256(bytes(name)),\n keccak256(bytes(\"1\")),\n chainId,\n address(this)\n )\n );\n }\n\n function _mint(address to, uint256 value) internal {\n totalSupply = totalSupply.add(value);\n balanceOf[to] = balanceOf[to].add(value);\n emit Transfer(address(0), to, value);\n }\n\n function _burn(address from, uint256 value) internal {\n balanceOf[from] = balanceOf[from].sub(value);\n totalSupply = totalSupply.sub(value);\n emit Transfer(from, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) private {\n allowance[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _transfer(address from, address to, uint256 value) private {\n balanceOf[from] = balanceOf[from].sub(value);\n balanceOf[to] = balanceOf[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function approve(\n address spender,\n uint256 value\n ) external override returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transfer(\n address to,\n uint256 value\n ) external override returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 value\n ) external override returns (bool) {\n allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);\n\n _transfer(from, to, value);\n return true;\n }\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external override {\n require(deadline >= block.timestamp, \"EXPIRED\");\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(\n recoveredAddress != address(0) && recoveredAddress == owner,\n \"INVALID_SIGNATURE\"\n );\n _approve(owner, spender, value);\n }\n\n function mintInternal(address account, uint256 amount) public {\n _mint(account, amount);\n }\n\n function getPermitDigest(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline\n ) public view returns (bytes32) {\n return\n keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner],\n deadline\n )\n )\n )\n );\n }\n}\n" + }, + "contracts/SonneMerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.19;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {SecureMerkleTrie} from \"@eth-optimism/contracts-bedrock/contracts/libraries/trie/SecureMerkleTrie.sol\";\nimport {RLPReader} from \"@eth-optimism/contracts-bedrock/contracts/libraries/rlp/RLPReader.sol\";\nimport {ISonneMerkleDistributor} from \"./interfaces/ISonneMerkleDistributor.sol\";\n\n/// @title Sonne Finance Merkle tree-based rewards distributor\n/// @notice Contract to distribute rewards on BASE network to Sonne Finance Optimism stakers\ncontract SonneMerkleDistributor is\n ReentrancyGuard,\n Ownable,\n ISonneMerkleDistributor\n{\n using SafeERC20 for IERC20;\n\n struct Reward {\n uint256 balance; // amount of reward tokens held in this reward\n bytes32 merkleRoot; // root of claims merkle tree\n uint256 withdrawUnlockTime; // time after which owner can withdraw remaining rewards\n uint256 ratio; // ratio of rewards to be distributed per one staked token on OP\n mapping(bytes32 => bool) leafClaimed; // mapping of leafes that already claimed\n }\n\n IERC20 public immutable rewardToken;\n uint256[] public rewards; // a list of all rewards\n\n mapping(uint256 => Reward) public Rewards; // mapping between blockNumber => Reward\n mapping(address => address) public delegatorAddresses;\n\n /// mapping to allow msg.sender to claim on behalf of a delegators address\n\n /// @notice Contract constructor to initialize rewardToken\n /// @param _rewardToken The reward token to be distributed\n constructor(IERC20 _rewardToken) {\n require(address(_rewardToken) != address(0), \"Token cannot be zero\");\n rewardToken = _rewardToken;\n }\n\n /// @notice Sets a delegator address for a given recipient\n /// @param _recipient original eligible recipient address\n /// @param _delegator The address that sould claim on behalf of the owner\n function setDelegator(\n address _recipient,\n address _delegator\n ) external onlyOwner {\n require(\n _recipient != address(0) && _delegator != address(0),\n \"Invalid address provided\"\n );\n delegatorAddresses[_delegator] = _recipient;\n }\n\n /// @notice Creates a new Reward struct for a rewards distribution\n /// @param amount The amount of reward tokens to deposit\n /// @param merkleRoot The merkle root of the distribution tree\n /// @param blockNumber The block number for the Reward\n /// @param withdrawUnlockTime The timestamp after which withdrawals by owner are allowed\n /// @param totalStakedBalance Total staked balance of the merkleRoot (computed off-chain)\n function addReward(\n uint256 amount,\n bytes32 merkleRoot,\n uint256 blockNumber,\n uint256 withdrawUnlockTime,\n uint256 totalStakedBalance\n ) external onlyOwner {\n require(merkleRoot != bytes32(0), \"Merkle root cannot be zero\");\n\n // creates a new reward struct tied to the blocknumber the merkleProof was created at\n Reward storage reward = Rewards[blockNumber];\n\n require(\n reward.merkleRoot == bytes32(0),\n \"Merkle root was already posted\"\n );\n uint256 balance = rewardToken.balanceOf(msg.sender);\n require(\n amount > 0 && amount <= balance,\n \"Invalid amount or insufficient balance\"\n );\n\n // transfer rewardToken from the distributor to the contract\n rewardToken.safeTransferFrom(msg.sender, address(this), amount);\n\n // record Reward in stable storage\n reward.balance = amount;\n reward.merkleRoot = merkleRoot;\n reward.withdrawUnlockTime = withdrawUnlockTime;\n reward.ratio = (amount * 1e18) / (totalStakedBalance);\n rewards.push(blockNumber);\n emit NewMerkle(\n msg.sender,\n address(rewardToken),\n amount,\n merkleRoot,\n blockNumber,\n withdrawUnlockTime\n );\n }\n\n /// @notice Allows to withdraw available funds to owner after unlock time\n /// @param blockNumber The block number for the Reward\n /// @param amount The amount to withdraw\n function withdrawFunds(\n uint256 blockNumber,\n uint256 amount\n ) external onlyOwner {\n Reward storage reward = Rewards[blockNumber];\n require(\n block.timestamp >= reward.withdrawUnlockTime,\n \"Rewards may not be withdrawn\"\n );\n require(amount <= reward.balance, \"Insufficient balance\");\n\n // update Rewards record\n reward.balance = reward.balance -= amount;\n\n // transfer rewardToken back to owner\n rewardToken.safeTransfer(msg.sender, amount);\n emit MerkleFundUpdate(\n msg.sender,\n reward.merkleRoot,\n blockNumber,\n amount,\n true\n );\n }\n\n /// @notice Claims the specified amount for an account if valid\n /// @dev Checks proofs and claims tracking before transferring rewardTokens\n /// @param blockNumber The block number for the Reward\n /// @param proof The merkle proof for the claim\n function claim(\n uint256 blockNumber,\n bytes[] calldata proof\n ) external nonReentrant {\n Reward storage reward = Rewards[blockNumber];\n require(reward.merkleRoot != bytes32(0), \"Reward not found\");\n\n // Check if the delegatorAddresses includes the account\n // The delegatorAddresses mapping allows for an account to delegate its claim ability to another address\n // This can be useful in scenarios where the target recipient might not have the ability to directly interact\n // with the BASE network contract (e.g. a smart contract with a different address)\n address recipient = delegatorAddresses[msg.sender] != address(0)\n ? delegatorAddresses[msg.sender]\n : msg.sender;\n\n // Assuming slotNr is 2 as per your previous function\n bytes32 key = keccak256(abi.encode(recipient, uint256(2)));\n\n //Get the amount of the key from the merkel tree\n uint256 amount = _getValueFromMerkleTree(reward.merkleRoot, key, proof);\n\n // calculate the reward based on the ratio\n uint256 rewardAmount = (amount * reward.ratio) / 1e18; // TODO check if there is a loss of precision possible here\n\n require(\n reward.balance >= rewardAmount,\n \"Claim under-funded by funder.\"\n );\n require(\n Rewards[blockNumber].leafClaimed[key] == false,\n \"Already claimed\"\n );\n\n // marks the leaf as claimed\n reward.leafClaimed[key] = true;\n\n // Subtract the rewardAmount, not the amount\n reward.balance = reward.balance - rewardAmount;\n\n //Send reward tokens to the recipient\n rewardToken.safeTransfer(recipient, rewardAmount);\n\n emit MerkleClaim(\n recipient,\n address(rewardToken),\n blockNumber,\n rewardAmount\n );\n }\n\n /// @notice Checks if a claim is valid and claimable\n /// @param blockNumber The block number for the Reward\n /// @param account The address of the account claiming\n /// @param proof The merkle proof for the claim\n /// @return A bool indicating if the claim is valid and claimable\n function isClaimable(\n uint256 blockNumber,\n address account,\n bytes[] calldata proof\n ) external view returns (bool) {\n bytes32 merkleRoot = Rewards[blockNumber].merkleRoot;\n\n // At the staking contract, the balances are stored in a mapping (address => uint256) at storage slot 2\n bytes32 leaf = keccak256(abi.encode(account, uint256(2)));\n\n if (merkleRoot == 0) return false;\n return\n !Rewards[blockNumber].leafClaimed[leaf] &&\n _getValueFromMerkleTree(merkleRoot, leaf, proof) > 0;\n }\n\n /// @dev Uses SecureMerkleTrie Library to extract the value from the Merkle proof provided by the user\n /// @param merkleRoot the merkle root\n /// @param key the key of the leaf => keccak256(address,2)\n /// @return result The converted uint256 value as stored in the slot on OP\n function _getValueFromMerkleTree(\n bytes32 merkleRoot,\n bytes32 key,\n bytes[] calldata proof\n ) internal pure returns (uint256 result) {\n // Uses SecureMerkleTrie Library to extract the value from the Merkle proof provided by the user\n // Reverts if Merkle proof verification fails\n bytes memory data = RLPReader.readBytes(\n SecureMerkleTrie.get(abi.encodePacked(key), proof, merkleRoot)\n );\n\n for (uint256 i = 0; i < data.length; i++) {\n result = result * 256 + uint8(data[i]);\n }\n }\n}\n" + }, + "contracts/TestContract.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.19;\n\ncontract TestContract {\n address public owner;\n //Fake vars to move shares mapping at slot number 2\n uint256 private bar;\n\n mapping(address => uint256) public shares;\n\n function mint(address account, uint256 amount) public {\n require(msg.sender == owner, \"only owner\");\n shares[account] = amount;\n }\n\n constructor() {\n owner = msg.sender;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/crosschain-rewards/hardhat.config.ts b/crosschain-rewards/hardhat.config.ts index b3b403d..b4d28e1 100644 --- a/crosschain-rewards/hardhat.config.ts +++ b/crosschain-rewards/hardhat.config.ts @@ -1,32 +1,53 @@ -import { HardhatUserConfig } from "hardhat/config"; -import "@nomicfoundation/hardhat-toolbox"; +import * as dotenv from 'dotenv'; +dotenv.config(); -import '@typechain/hardhat' -import '@nomicfoundation/hardhat-ethers' -import '@nomicfoundation/hardhat-chai-matchers' -import '@nomiclabs/hardhat-truffle5' -import "@nomicfoundation/hardhat-network-helpers"; +import { HardhatUserConfig } from 'hardhat/config'; +import '@nomicfoundation/hardhat-toolbox'; +import '@typechain/hardhat'; +import '@nomicfoundation/hardhat-ethers'; +import '@nomicfoundation/hardhat-chai-matchers'; +import '@nomiclabs/hardhat-truffle5'; +import '@nomicfoundation/hardhat-network-helpers'; +import 'hardhat-deploy'; const config: HardhatUserConfig = { - solidity: { - version: "0.8.19", settings: { - optimizer: { - enabled: true, - runs: 1000, - }, + solidity: { + version: '0.8.19', + settings: { + optimizer: { + enabled: true, + runs: 1000, + }, + }, + }, + typechain: { + outDir: 'src/types', + target: 'ethers-v6', + alwaysGenerateOverloads: false, // should overloads with full signatures like deposit(uint256) be generated always, even if there are no overloads? + externalArtifacts: ['externalArtifacts/*.json'], // optional array of glob patterns with external artifacts to process (for example external libs from node_modules) + dontOverrideCompile: false, // defaults to false + }, + networks: { + hardhat: {}, + base: { + chainId: 8453, + url: process.env.BASE_RPC_URL!, + //ovm: true, + accounts: [process.env.BASE_DEPLOYER_KEY!], + verify: { + etherscan: { + apiUrl: 'https://api.basescan.org', + apiKey: process.env.BASE_ETHERSCAN_KEY, + }, + }, + }, + }, + namedAccounts: { + deployer: { + default: 0, + }, }, - }, - typechain: { - outDir: 'src/types', - target: 'ethers-v6', - alwaysGenerateOverloads: false, // should overloads with full signatures like deposit(uint256) be generated always, even if there are no overloads? - externalArtifacts: ['externalArtifacts/*.json'], // optional array of glob patterns with external artifacts to process (for example external libs from node_modules) - dontOverrideCompile: false // defaults to false - }, - networks: { - hardhat: {} - } }; export default config; diff --git a/crosschain-rewards/package-lock.json b/crosschain-rewards/package-lock.json index e5369ca..58432c7 100644 --- a/crosschain-rewards/package-lock.json +++ b/crosschain-rewards/package-lock.json @@ -24,6 +24,7 @@ "chai": "^4.3.7", "ethers": "^6.7.0", "hardhat": "^2.17.1", + "hardhat-deploy": "^0.11.37", "mocha": "^10.2.0", "typechain": "^8.3.1", "typescript": "^5.1.6", @@ -3031,8 +3032,7 @@ "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/readable-stream": { "version": "2.3.15", @@ -3478,6 +3478,15 @@ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", "dev": true }, + "node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -4955,6 +4964,12 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/encode-utf8": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", + "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==", + "dev": true + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -6427,6 +6442,15 @@ "flat": "cli.js" } }, + "node_modules/fmix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz", + "integrity": "sha512-Y6hyofImk9JdzU8k5INtTXX1cu8LDlePWDFU5sftm9H+zKCr5SGrVjdhkvsim646cw5zD0nADj8oHyXMZmCZ9w==", + "dev": true, + "dependencies": { + "imul": "^1.0.0" + } + }, "node_modules/follow-redirects": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", @@ -6982,6 +7006,208 @@ } } }, + "node_modules/hardhat-deploy": { + "version": "0.11.37", + "resolved": "https://registry.npmjs.org/hardhat-deploy/-/hardhat-deploy-0.11.37.tgz", + "integrity": "sha512-pohPSEEo/X9Yfv0Fc0kXBQW6JO0LNOILBGCP69Ci1COJvLht1hLjAtXt/hccyvD9qY/uwJAM75fmsf41Y9N7lg==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/contracts": "^5.7.0", + "@ethersproject/providers": "^5.7.2", + "@ethersproject/solidity": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wallet": "^5.7.0", + "@types/qs": "^6.9.7", + "axios": "^0.21.1", + "chalk": "^4.1.2", + "chokidar": "^3.5.2", + "debug": "^4.3.2", + "enquirer": "^2.3.6", + "ethers": "^5.5.3", + "form-data": "^4.0.0", + "fs-extra": "^10.0.0", + "match-all": "^1.2.6", + "murmur-128": "^0.2.1", + "qs": "^6.9.4", + "zksync-web3": "^0.14.3" + } + }, + "node_modules/hardhat-deploy/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/hardhat-deploy/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/hardhat-deploy/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/hardhat-deploy/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/hardhat-deploy/node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/hardhat-deploy/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hardhat-deploy/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/hardhat-deploy/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hardhat-deploy/node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hardhat-deploy/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/hardhat-deploy/node_modules/zksync-web3": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/zksync-web3/-/zksync-web3-0.14.3.tgz", + "integrity": "sha512-hT72th4AnqyLW1d5Jlv8N2B/qhEnl2NePK2A3org7tAa24niem/UAaHMkEvmWI3SF9waYUPtqAtjpf+yvQ9zvQ==", + "dev": true, + "peerDependencies": { + "ethers": "^5.7.0" + } + }, "node_modules/hardhat-gas-reporter": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz", @@ -7427,6 +7653,15 @@ "integrity": "sha512-oGXzbEDem9OOpDWZu88jGiYCvIsLHMvGw+8OXlpsvTFvIQplQbjg1B1cvKg8f7Hoch6+NGjpPsH1Fr+Mc2D1aA==", "dev": true }, + "node_modules/imul": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz", + "integrity": "sha512-WFAgfwPLAjU66EKt6vRdTlKj4nAgIDQzh29JonLa4Bqtl6D8JrIMvWjCnx7xEjVNmP3U0fM5o8ZObk7d0f62bA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", @@ -8341,6 +8576,12 @@ "dev": true, "peer": true }, + "node_modules/match-all": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/match-all/-/match-all-1.2.6.tgz", + "integrity": "sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ==", + "dev": true + }, "node_modules/mcl-wasm": { "version": "0.7.9", "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", @@ -8861,6 +9102,17 @@ "buffer": "^5.5.0" } }, + "node_modules/murmur-128": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/murmur-128/-/murmur-128-0.2.1.tgz", + "integrity": "sha512-WseEgiRkI6aMFBbj8Cg9yBj/y+OdipwVC7zUo3W2W1JAJITwouUOtpqsmGSg67EQmwwSyod7hsVsWY5LsrfQVg==", + "dev": true, + "dependencies": { + "encode-utf8": "^1.0.2", + "fmix": "^0.1.0", + "imul": "^1.0.0" + } + }, "node_modules/nano-base32": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/nano-base32/-/nano-base32-1.0.1.tgz", diff --git a/crosschain-rewards/package.json b/crosschain-rewards/package.json index 75f5316..5c3fab2 100644 --- a/crosschain-rewards/package.json +++ b/crosschain-rewards/package.json @@ -16,6 +16,7 @@ "chai": "^4.3.7", "ethers": "^6.7.0", "hardhat": "^2.17.1", + "hardhat-deploy": "^0.11.37", "mocha": "^10.2.0", "typechain": "^8.3.1", "typescript": "^5.1.6", diff --git a/crosschain-rewards/scripts/getAccountRoot.ts b/crosschain-rewards/scripts/getAccountRoot.ts index 136ccba..1b50127 100644 --- a/crosschain-rewards/scripts/getAccountRoot.ts +++ b/crosschain-rewards/scripts/getAccountRoot.ts @@ -1,16 +1,16 @@ -import hre, { ethers } from "hardhat" -import { createSnaptshot } from "../src/op/createSnapshot" - +import hre, { ethers } from 'hardhat'; +import { createSnaptshot } from '../src/op/createSnapshot'; async function main() { - const provider = new ethers.JsonRpcProvider("https://opt-mainnet.g.alchemy.com/v2/o0342IMrRLY_Uj8PNpCRebPwMn1n1ql5") - - const uSonne = "0x41279e29586eb20f9a4f65e031af09fced171166" - const blockNr = 108080039 - const s = await createSnaptshot(provider, uSonne, blockNr) + const provider = new ethers.JsonRpcProvider( + 'https://opt-mainnet.g.alchemy.com/v2/o0342IMrRLY_Uj8PNpCRebPwMn1n1ql5', + ); - console.log(s) + const uSonne = '0x41279e29586eb20f9a4f65e031af09fced171166'; + const blockNr = 108080039; + const s = await createSnaptshot(provider, uSonne, blockNr); + console.log(s); } // We recommend this pattern to be able to use async/await everywhere @@ -18,4 +18,4 @@ async function main() { main().catch((error) => { console.error(error); process.exitCode = 1; -}); \ No newline at end of file +}); diff --git a/crosschain-rewards/scripts/getProofForUser.ts b/crosschain-rewards/scripts/getProofForUser.ts index 270d631..0fde072 100644 --- a/crosschain-rewards/scripts/getProofForUser.ts +++ b/crosschain-rewards/scripts/getProofForUser.ts @@ -1,18 +1,18 @@ -import { ethers } from "hardhat" -import { getProofForUserShares } from "../src/op/getProofForUserShares" - +import { ethers } from 'hardhat'; +import { getProofForUserShares } from '../src/op/getProofForUserShares'; async function main() { - const provider = new ethers.JsonRpcProvider("https://opt-mainnet.g.alchemy.com/v2/o0342IMrRLY_Uj8PNpCRebPwMn1n1ql5") - - const uSonne = "0x41279e29586eb20f9a4f65e031af09fced171166" - const addr = "0xdAD29981B5FeeFEeaf3eF92E678e53c5620A1Fd8" - const blockNr = 108080039 + const provider = new ethers.JsonRpcProvider( + 'https://opt-mainnet.g.alchemy.com/v2/o0342IMrRLY_Uj8PNpCRebPwMn1n1ql5', + ); - const proof = await getProofForUserShares(provider, uSonne, addr, blockNr) + const uSonne = '0x41279e29586eb20f9a4f65e031af09fced171166'; + const addr = '0xdAD29981B5FeeFEeaf3eF92E678e53c5620A1Fd8'; + const blockNr = 108080039; - console.log(proof) + const proof = await getProofForUserShares(provider, uSonne, addr, blockNr); + console.log(proof); } // We recommend this pattern to be able to use async/await everywhere @@ -20,4 +20,4 @@ async function main() { main().catch((error) => { console.error(error); process.exitCode = 1; -}); \ No newline at end of file +}); diff --git a/crosschain-rewards/src/types/factories/@openzeppelin/contracts/token/ERC20/ERC20__factory.ts b/crosschain-rewards/src/types/factories/@openzeppelin/contracts/token/ERC20/ERC20__factory.ts index 946f05c..7d33adc 100644 --- a/crosschain-rewards/src/types/factories/@openzeppelin/contracts/token/ERC20/ERC20__factory.ts +++ b/crosschain-rewards/src/types/factories/@openzeppelin/contracts/token/ERC20/ERC20__factory.ts @@ -304,7 +304,7 @@ const _abi = [ ] as const; const _bytecode = - "0x60806040523480156200001157600080fd5b5060405162000c4238038062000c4283398101604081905262000034916200011f565b600362000042838262000218565b50600462000051828262000218565b505050620002e4565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200008257600080fd5b81516001600160401b03808211156200009f576200009f6200005a565b604051601f8301601f19908116603f01168101908282118183101715620000ca57620000ca6200005a565b81604052838152602092508683858801011115620000e757600080fd5b600091505b838210156200010b5785820183015181830184015290820190620000ec565b600093810190920192909252949350505050565b600080604083850312156200013357600080fd5b82516001600160401b03808211156200014b57600080fd5b620001598683870162000070565b935060208501519150808211156200017057600080fd5b506200017f8582860162000070565b9150509250929050565b600181811c908216806200019e57607f821691505b602082108103620001bf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200021357600081815260208120601f850160051c81016020861015620001ee5750805b601f850160051c820191505b818110156200020f57828155600101620001fa565b5050505b505050565b81516001600160401b038111156200023457620002346200005a565b6200024c8162000245845462000189565b84620001c5565b602080601f8311600181146200028457600084156200026b5750858301515b600019600386901b1c1916600185901b1785556200020f565b600085815260208120601f198616915b82811015620002b55788860151825594840194600190910190840162000294565b5085821015620002d45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61094e80620002f46000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80633950935111610081578063a457c2d71161005b578063a457c2d714610187578063a9059cbb1461019a578063dd62ed3e146101ad57600080fd5b8063395093511461014357806370a082311461015657806395d89b411461017f57600080fd5b806318160ddd116100b257806318160ddd1461010f57806323b872dd14610121578063313ce5671461013457600080fd5b806306fdde03146100ce578063095ea7b3146100ec575b600080fd5b6100d66101e6565b6040516100e39190610798565b60405180910390f35b6100ff6100fa366004610802565b610278565b60405190151581526020016100e3565b6002545b6040519081526020016100e3565b6100ff61012f36600461082c565b610292565b604051601281526020016100e3565b6100ff610151366004610802565b6102b6565b610113610164366004610868565b6001600160a01b031660009081526020819052604090205490565b6100d66102f5565b6100ff610195366004610802565b610304565b6100ff6101a8366004610802565b6103b3565b6101136101bb36600461088a565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6060600380546101f5906108bd565b80601f0160208091040260200160405190810160405280929190818152602001828054610221906108bd565b801561026e5780601f106102435761010080835404028352916020019161026e565b820191906000526020600020905b81548152906001019060200180831161025157829003601f168201915b5050505050905090565b6000336102868185856103c1565b60019150505b92915050565b6000336102a0858285610519565b6102ab8585856105ab565b506001949350505050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919061028690829086906102f09087906108f7565b6103c1565b6060600480546101f5906108bd565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909190838110156103a65760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102ab82868684036103c1565b6000336102868185856105ab565b6001600160a01b03831661043c5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161039d565b6001600160a01b0382166104b85760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161039d565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146105a557818110156105985760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161039d565b6105a584848484036103c1565b50505050565b6001600160a01b0383166106275760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161039d565b6001600160a01b0382166106a35760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161039d565b6001600160a01b038316600090815260208190526040902054818110156107325760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161039d565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36105a5565b600060208083528351808285015260005b818110156107c5578581018301518582016040015282016107a9565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146107fd57600080fd5b919050565b6000806040838503121561081557600080fd5b61081e836107e6565b946020939093013593505050565b60008060006060848603121561084157600080fd5b61084a846107e6565b9250610858602085016107e6565b9150604084013590509250925092565b60006020828403121561087a57600080fd5b610883826107e6565b9392505050565b6000806040838503121561089d57600080fd5b6108a6836107e6565b91506108b4602084016107e6565b90509250929050565b600181811c908216806108d157607f821691505b6020821081036108f157634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561028c57634e487b7160e01b600052601160045260246000fdfea2646970667358221220ec0d48dd141663fcadcd39bd3566c8fef6e7bbf832cddc90e83e0389b23caf4d64736f6c63430008130033"; + "0x60806040523480156200001157600080fd5b5060405162000c4238038062000c4283398101604081905262000034916200011f565b600362000042838262000218565b50600462000051828262000218565b505050620002e4565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200008257600080fd5b81516001600160401b03808211156200009f576200009f6200005a565b604051601f8301601f19908116603f01168101908282118183101715620000ca57620000ca6200005a565b81604052838152602092508683858801011115620000e757600080fd5b600091505b838210156200010b5785820183015181830184015290820190620000ec565b600093810190920192909252949350505050565b600080604083850312156200013357600080fd5b82516001600160401b03808211156200014b57600080fd5b620001598683870162000070565b935060208501519150808211156200017057600080fd5b506200017f8582860162000070565b9150509250929050565b600181811c908216806200019e57607f821691505b602082108103620001bf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200021357600081815260208120601f850160051c81016020861015620001ee5750805b601f850160051c820191505b818110156200020f57828155600101620001fa565b5050505b505050565b81516001600160401b038111156200023457620002346200005a565b6200024c8162000245845462000189565b84620001c5565b602080601f8311600181146200028457600084156200026b5750858301515b600019600386901b1c1916600185901b1785556200020f565b600085815260208120601f198616915b82811015620002b55788860151825594840194600190910190840162000294565b5085821015620002d45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61094e80620002f46000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80633950935111610081578063a457c2d71161005b578063a457c2d714610187578063a9059cbb1461019a578063dd62ed3e146101ad57600080fd5b8063395093511461014357806370a082311461015657806395d89b411461017f57600080fd5b806318160ddd116100b257806318160ddd1461010f57806323b872dd14610121578063313ce5671461013457600080fd5b806306fdde03146100ce578063095ea7b3146100ec575b600080fd5b6100d66101e6565b6040516100e39190610798565b60405180910390f35b6100ff6100fa366004610802565b610278565b60405190151581526020016100e3565b6002545b6040519081526020016100e3565b6100ff61012f36600461082c565b610292565b604051601281526020016100e3565b6100ff610151366004610802565b6102b6565b610113610164366004610868565b6001600160a01b031660009081526020819052604090205490565b6100d66102f5565b6100ff610195366004610802565b610304565b6100ff6101a8366004610802565b6103b3565b6101136101bb36600461088a565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6060600380546101f5906108bd565b80601f0160208091040260200160405190810160405280929190818152602001828054610221906108bd565b801561026e5780601f106102435761010080835404028352916020019161026e565b820191906000526020600020905b81548152906001019060200180831161025157829003601f168201915b5050505050905090565b6000336102868185856103c1565b60019150505b92915050565b6000336102a0858285610519565b6102ab8585856105ab565b506001949350505050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919061028690829086906102f09087906108f7565b6103c1565b6060600480546101f5906108bd565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909190838110156103a65760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102ab82868684036103c1565b6000336102868185856105ab565b6001600160a01b03831661043c5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161039d565b6001600160a01b0382166104b85760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161039d565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146105a557818110156105985760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161039d565b6105a584848484036103c1565b50505050565b6001600160a01b0383166106275760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161039d565b6001600160a01b0382166106a35760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161039d565b6001600160a01b038316600090815260208190526040902054818110156107325760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161039d565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36105a5565b600060208083528351808285015260005b818110156107c5578581018301518582016040015282016107a9565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146107fd57600080fd5b919050565b6000806040838503121561081557600080fd5b61081e836107e6565b946020939093013593505050565b60008060006060848603121561084157600080fd5b61084a846107e6565b9250610858602085016107e6565b9150604084013590509250925092565b60006020828403121561087a57600080fd5b610883826107e6565b9392505050565b6000806040838503121561089d57600080fd5b6108a6836107e6565b91506108b4602084016107e6565b90509250929050565b600181811c908216806108d157607f821691505b6020821081036108f157634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561028c57634e487b7160e01b600052601160045260246000fdfea264697066735822122098835bb08221f924058230f87e9e398dff4ea334c7c87535b57465327945f17c64736f6c63430008130033"; type ERC20ConstructorParams = | [signer?: Signer] diff --git a/crosschain-rewards/src/types/factories/contracts/Delegator.sol/Delegate__factory.ts b/crosschain-rewards/src/types/factories/contracts/Delegator.sol/Delegate__factory.ts index 08dd190..6c9e060 100644 --- a/crosschain-rewards/src/types/factories/contracts/Delegator.sol/Delegate__factory.ts +++ b/crosschain-rewards/src/types/factories/contracts/Delegator.sol/Delegate__factory.ts @@ -88,7 +88,7 @@ const _abi = [ ] as const; const _bytecode = - "0x608060405234801561001057600080fd5b506101aa806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063544d856414610046578063587cde1e1461008e578063ca5eb5e1146100b7575b600080fd5b610072610054366004610144565b6001600160a01b039081166000908152602081905260409020541690565b6040516001600160a01b03909116815260200160405180910390f35b61007261009c366004610144565b6000602081905290815260409020546001600160a01b031681565b6100ca6100c5366004610144565b6100cc565b005b336000818152602081815260409182902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03861690811790915591519182527fef9fc1dee6010109e6e3b21e51d44028e246dbad8a5a71ea192a30b19e1f457f910160405180910390a250565b60006020828403121561015657600080fd5b81356001600160a01b038116811461016d57600080fd5b939250505056fea2646970667358221220b640b3a9f7607fdcc8f02863a9b767c069bb15133a8563eb6b1b92c564a0d70364736f6c63430008130033"; + "0x608060405234801561001057600080fd5b506101aa806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063544d856414610046578063587cde1e1461008e578063ca5eb5e1146100b7575b600080fd5b610072610054366004610144565b6001600160a01b039081166000908152602081905260409020541690565b6040516001600160a01b03909116815260200160405180910390f35b61007261009c366004610144565b6000602081905290815260409020546001600160a01b031681565b6100ca6100c5366004610144565b6100cc565b005b336000818152602081815260409182902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03861690811790915591519182527fef9fc1dee6010109e6e3b21e51d44028e246dbad8a5a71ea192a30b19e1f457f910160405180910390a250565b60006020828403121561015657600080fd5b81356001600160a01b038116811461016d57600080fd5b939250505056fea26469706673582212203c53d5c43278b70b10f17769e0149b57f184fae3f8985f1d647f3d3e42b1293f64736f6c63430008130033"; type DelegateConstructorParams = | [signer?: Signer] diff --git a/crosschain-rewards/src/types/factories/contracts/SonneMerkleDistributor__factory.ts b/crosschain-rewards/src/types/factories/contracts/SonneMerkleDistributor__factory.ts index a0d0796..2a98a2a 100644 --- a/crosschain-rewards/src/types/factories/contracts/SonneMerkleDistributor__factory.ts +++ b/crosschain-rewards/src/types/factories/contracts/SonneMerkleDistributor__factory.ts @@ -398,7 +398,7 @@ const _abi = [ ] as const; const _bytecode = - "0x60a06040523480156200001157600080fd5b506040516200320138038062003201833981016040819052620000349162000103565b60016000556200004433620000b1565b6001600160a01b0381166200009f5760405162461bcd60e51b815260206004820152601460248201527f546f6b656e2063616e6e6f74206265207a65726f000000000000000000000000604482015260640160405180910390fd5b6001600160a01b031660805262000135565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602082840312156200011657600080fd5b81516001600160a01b03811681146200012e57600080fd5b9392505050565b6080516130866200017b600039600081816101e1015281816104730152818161049d01528181610761015281816108650152818161090d0152610a5201526130866000f3fe608060405234801561001057600080fd5b50600436106100d35760003560e01c80639366452c11610081578063f301af421161005b578063f301af42146101bb578063f7c618c1146101dc578063f8738c251461020357600080fd5b80639366452c14610182578063e525310514610195578063f2fde38b146101a857600080fd5b80636d46379b116100b25780636d46379b14610146578063715018a6146101695780638da5cb5b1461017157600080fd5b8062501e28146100d85780631ce92be5146100ed57806341f891a414610100575b600080fd5b6100eb6100e6366004612c03565b61025a565b005b6100eb6100fb366004612c6b565b61051c565b61012961010e366004612c9e565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610159610154366004612cb9565b6105cd565b604051901515815260200161013d565b6100eb610667565b6001546001600160a01b0316610129565b6100eb610190366004612d13565b61067b565b6100eb6101a3366004612d4e565b61096e565b6100eb6101b6366004612c9e565b610ac9565b6101ce6101c9366004612d70565b610b59565b60405190815260200161013d565b6101297f000000000000000000000000000000000000000000000000000000000000000081565b61023a610211366004612d70565b600360208190526000918252604090912080546001820154600283015492909301549092919084565b60408051948552602085019390935291830152606082015260800161013d565b610262610b7a565b600083815260036020526040902060018101546102c65760405162461bcd60e51b815260206004820152601060248201527f526577617264206e6f7420666f756e640000000000000000000000000000000060448201526064015b60405180910390fd5b336000908152600460205260408120546001600160a01b03166102e95733610303565b336000908152600460205260409020546001600160a01b03165b604080516001600160a01b038316602082015260029181019190915290915060009060600160405160208183030381529060405280519060200120905060006103528460010154838888610bd3565b90506000670de0b6b3a764000085600301548361036f9190612d9f565b6103799190612dcc565b905080856000015410156103cf5760405162461bcd60e51b815260206004820152601d60248201527f436c61696d20756e6465722d66756e6465642062792066756e6465722e00000060448201526064016102bd565b600088815260036020908152604080832086845260040190915290205460ff161561043c5760405162461bcd60e51b815260206004820152600f60248201527f416c726561647920636c61696d6564000000000000000000000000000000000060448201526064016102bd565b60008381526004860160205260409020805460ff191660011790558454610464908290612de0565b855561049a6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168583610c70565b877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b03167fceea116ca90ae38b5f3bcd7482763d0bdd5915faed2146d37b1e3bcd1ea425378460405161050091815260200190565b60405180910390a450505050506105176001600055565b505050565b610524610d19565b6001600160a01b0382161580159061054457506001600160a01b03811615155b6105905760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420616464726573732070726f7669646564000000000000000060448201526064016102bd565b6001600160a01b03908116600090815260046020526040902080549190921673ffffffffffffffffffffffffffffffffffffffff19909116179055565b60008481526003602090815260408083206001015481516001600160a01b038816818501526002818401528251808203840181526060909101909252815191909201208183036106225760009250505061065f565b600087815260036020908152604080832084845260040190915290205460ff1615801561065a5750600061065883838888610bd3565b115b925050505b949350505050565b61066f610d19565b6106796000610d73565b565b610683610d19565b836106d05760405162461bcd60e51b815260206004820152601a60248201527f4d65726b6c6520726f6f742063616e6e6f74206265207a65726f00000000000060448201526064016102bd565b60008381526003602052604090206001810154156107305760405162461bcd60e51b815260206004820152601e60248201527f4d65726b6c6520726f6f742077617320616c726561647920706f73746564000060448201526064016102bd565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156107b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d49190612df3565b90506000871180156107e65750808711155b6108585760405162461bcd60e51b815260206004820152602660248201527f496e76616c696420616d6f756e74206f7220696e73756666696369656e74206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016102bd565b61088d6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308a610dd2565b8682556001820186905560028201849055826108b188670de0b6b3a7640000612d9f565b6108bb9190612dcc565b6003830155600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace01859055604080518881526020810187905290810185905286907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169033907f4993e379e2a0a87975314480436d8f2de32d291a64892cb63cdb0839d09044369060600160405180910390a450505050505050565b610976610d19565b600082815260036020526040902060028101544210156109d85760405162461bcd60e51b815260206004820152601c60248201527f52657761726473206d6179206e6f742062652077697468647261776e0000000060448201526064016102bd565b8054821115610a295760405162461bcd60e51b815260206004820152601460248201527f496e73756666696369656e742062616c616e636500000000000000000000000060448201526064016102bd565b81816000016000828254610a3d9190612de0565b9182905550825550610a796001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163384610c70565b6001808201546040805186815260208101869052908101929092529033907f210aece5a2bb3ac8bbec4d3bd83444123ef037a899b89d617e735799f983e6b39060600160405180910390a3505050565b610ad1610d19565b6001600160a01b038116610b4d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102bd565b610b5681610d73565b50565b60028181548110610b6957600080fd5b600091825260209091200154905081565b600260005403610bcc5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016102bd565b6002600055565b600080610c14610c0f86604051602001610bef91815260200190565b60408051601f19818403018152919052610c098688612e53565b89610e29565b610e4e565b905060005b8151811015610c6657818181518110610c3457610c34612f28565b016020015160f81c610c4884610100612d9f565b610c529190612f3e565b925080610c5e81612f51565b915050610c19565b5050949350505050565b6040516001600160a01b0383166024820152604481018290526105179084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610e67565b6001546001600160a01b031633146106795760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102bd565b600180546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6040516001600160a01b0380851660248301528316604482015260648101829052610e239085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610cb5565b50505050565b60606000610e3685610f4f565b9050610e43818585610f81565b9150505b9392505050565b6060610e61610e5c8361189d565b611959565b92915050565b6000610ebc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611a8e9092919063ffffffff16565b9050805160001480610edd575080806020019051810190610edd9190612f6a565b6105175760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016102bd565b60608180519060200120604051602001610f6b91815260200190565b6040516020818303038152906040529050919050565b60606000845111610fd45760405162461bcd60e51b815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b6579000000000000000000000060448201526064016102bd565b6000610fdf84611a9d565b90506000610fec86611b8c565b905060008460405160200161100391815260200190565b60405160208183030381529060405290506000805b845181101561182e57600085828151811061103557611035612f28565b6020026020010151905084518311156110b65760405162461bcd60e51b815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e67746800000000000000000000000000000000000060648201526084016102bd565b826000036111555780518051602091820120604051611104926110de92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b6111505760405162461bcd60e51b815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f74206861736800000060448201526064016102bd565b611278565b8051516020116111f1578051805160209182012060405161117f926110de92910190815260200190565b6111505760405162461bcd60e51b815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c20686173680000000000000000000000000000000000000000000000000060648201526084016102bd565b8051845160208087019190912082519190920120146112785760405162461bcd60e51b815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f652068617368000000000000000000000000000000000000000000000000000060648201526084016102bd565b61128460106001612f3e565b8160200151510361143157845183036113c95760006112c082602001516010815181106112b3576112b3612f28565b6020026020010151611959565b905060008151116113395760405162461bcd60e51b815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e636829000000000060648201526084016102bd565b600187516113479190612de0565b83146113bb5760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e63682900000000000060648201526084016102bd565b9650610e4795505050505050565b60008584815181106113dd576113dd612f28565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061140857611408612f28565b6020026020010151905061141b81611bef565b9550611428600186612f3e565b9450505061181b565b6002816020015151036117ad57600061144982611c14565b905060008160008151811061146057611460612f28565b016020015160f81c90506000611477600283612f8c565b611482906002612fae565b90506000611493848360ff16611c38565b905060006114a18a89611c38565b905060006114af8383611c6e565b9050808351146115275760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b657900000000000060648201526084016102bd565b60ff85166002148061153c575060ff85166003145b156116e257808251146115b75760405162461bcd60e51b815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e64657200000060648201526084016102bd565b60006115d388602001516001815181106112b3576112b3612f28565b9050600081511161164c5760405162461bcd60e51b815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c656166290000000000000060648201526084016102bd565b60018d5161165a9190612de0565b89146116ce5760405162461bcd60e51b815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c65616629000000000000000060648201526084016102bd565b9c50610e479b505050505050505050505050565b60ff851615806116f5575060ff85166001145b1561173457611721876020015160018151811061171457611714612f28565b6020026020010151611bef565b995061172d818a612f3e565b98506117a2565b60405162461bcd60e51b815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e20707265666978000000000000000000000000000060648201526084016102bd565b50505050505061181b565b60405162461bcd60e51b815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f646500000000000000000000000000000000000000000000000060648201526084016102bd565b508061182681612f51565b915050611018565b5060405162461bcd60e51b815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e747300000000000000000000000000000000000000000000000000000060648201526084016102bd565b6040805180820190915260008082526020820152600082511161193b5760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f206265606482015269206465636f6461626c6560b01b608482015260a4016102bd565b50604080518082019091528151815260209182019181019190915290565b6060600080600061196985611d05565b91945092509050600081600181111561198457611984612fc7565b146119f75760405162461bcd60e51b815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d0000000000000060648201526084016102bd565b611a018284612f3e565b855114611a765760405162461bcd60e51b815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e64657200000000000000000000000060648201526084016102bd565b611a85856020015184846125c7565b95945050505050565b606061065f8484600085612668565b805160609060008167ffffffffffffffff811115611abd57611abd612e0c565b604051908082528060200260200182016040528015611b0257816020015b6040805180820190915260608082526020820152815260200190600190039081611adb5790505b50905060005b82811015611b84576040518060400160405280868381518110611b2d57611b2d612f28565b60200260200101518152602001611b5c878481518110611b4f57611b4f612f28565b602002602001015161274f565b815250828281518110611b7157611b71612f28565b6020908102919091010152600101611b08565b509392505050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015611be4578060011b82018184015160001a8060041c8253600f811660018301535050600101611bb6565b509295945050505050565b60606020826000015110611c0b57611c0682611959565b610e61565b610e6182612762565b6060610e61611c3383602001516000815181106112b3576112b3612f28565b611b8c565b606082518210611c575750604080516020810190915260008152610e61565b610e478383848651611c699190612de0565b612778565b60008060008351855110611c83578351611c86565b84515b90505b8082108015611cf55750838281518110611ca557611ca5612f28565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858381518110611ce457611ce4612f28565b01602001516001600160f81b031916145b15611b8457816001019150611c89565b600080600080846000015111611d965760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f206265606482015269206465636f6461626c6560b01b608482015260a4016102bd565b6020840151805160001a607f8111611dbb5760006001600094509450945050506125c0565b60b78111611f65576000611dd0608083612de0565b905080876000015111611e715760405162461bcd60e51b815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a4016102bd565b6001838101516001600160f81b0319169082141580611eba57507f80000000000000000000000000000000000000000000000000000000000000006001600160f81b0319821610155b611f525760405162461bcd60e51b815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a4016102bd565b50600195509350600092506125c0915050565b60bf8111612233576000611f7a60b783612de0565b90508087600001511161201b5760405162461bcd60e51b815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a4016102bd565b60018301516001600160f81b03191660008190036120c75760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a4016102bd565b600184015160088302610100031c603781116121715760405162461bcd60e51b815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a4016102bd565b61217b8184612f3e565b8951116122165760405162461bcd60e51b815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a4016102bd565b612221836001612f3e565b97509550600094506125c09350505050565b60f781116122fa57600061224860c083612de0565b9050808760000151116122e95760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a4016102bd565b6001955093508492506125c0915050565b600061230760f783612de0565b9050808760000151116123a85760405162461bcd60e51b815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a4016102bd565b60018301516001600160f81b03191660008190036124545760405162461bcd60e51b815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a4016102bd565b600184015160088302610100031c603781116124fe5760405162461bcd60e51b815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a4016102bd565b6125088184612f3e565b8951116125a35760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a4016102bd565b6125ae836001612f3e565b97509550600194506125c09350505050565b9193909250565b606060008267ffffffffffffffff8111156125e4576125e4612e0c565b6040519080825280601f01601f19166020018201604052801561260e576020820181803683370190505b50905082600003612620579050610e47565b600061262c8587612f3e565b90506020820160005b8581101561264d578281015182820152602001612635565b8581111561265c576000868301525b50919695505050505050565b6060824710156126e05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016102bd565b600080866001600160a01b031685876040516126fc9190613001565b60006040518083038185875af1925050503d8060008114612739576040519150601f19603f3d011682016040523d82523d6000602084013e61273e565b606091505b509150915061065a878383876128e4565b6060610e6161275d8361189d565b61295d565b6060610e618260200151600084600001516125c7565b60608182601f0110156127cd5760405162461bcd60e51b815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016102bd565b82828401101561281f5760405162461bcd60e51b815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016102bd565b818301845110156128725760405162461bcd60e51b815260206004820152601160248201527f736c6963655f6f75744f66426f756e647300000000000000000000000000000060448201526064016102bd565b60608215801561289157604051915060008252602082016040526128db565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156128ca5780518352602092830192016128b2565b5050858452601f01601f1916604052505b50949350505050565b6060831561295357825160000361294c576001600160a01b0385163b61294c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102bd565b508161065f565b61065f8383612b8d565b6060600080600061296d85611d05565b91945092509050600181600181111561298857612988612fc7565b146129fb5760405162461bcd60e51b815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d000000000000000060648201526084016102bd565b8451612a078385612f3e565b14612a7a5760405162461bcd60e51b815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e646572000000000000000000000000000060648201526084016102bd565b6040805160208082526104208201909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081612a935790505090506000845b8751811015612b8157600080612b066040518060400160405280858d60000151612aea9190612de0565b8152602001858d60200151612aff9190612f3e565b9052611d05565b509150915060405180604001604052808383612b229190612f3e565b8152602001848c60200151612b379190612f3e565b815250858581518110612b4c57612b4c612f28565b6020908102919091010152612b62600185612f3e565b9350612b6e8183612f3e565b612b789084612f3e565b92505050612ac0565b50815295945050505050565b815115612b9d5781518083602001fd5b8060405162461bcd60e51b81526004016102bd919061301d565b60008083601f840112612bc957600080fd5b50813567ffffffffffffffff811115612be157600080fd5b6020830191508360208260051b8501011115612bfc57600080fd5b9250929050565b600080600060408486031215612c1857600080fd5b83359250602084013567ffffffffffffffff811115612c3657600080fd5b612c4286828701612bb7565b9497909650939450505050565b80356001600160a01b0381168114612c6657600080fd5b919050565b60008060408385031215612c7e57600080fd5b612c8783612c4f565b9150612c9560208401612c4f565b90509250929050565b600060208284031215612cb057600080fd5b610e4782612c4f565b60008060008060608587031215612ccf57600080fd5b84359350612cdf60208601612c4f565b9250604085013567ffffffffffffffff811115612cfb57600080fd5b612d0787828801612bb7565b95989497509550505050565b600080600080600060a08688031215612d2b57600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060408385031215612d6157600080fd5b50508035926020909101359150565b600060208284031215612d8257600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e6157610e61612d89565b634e487b7160e01b600052601260045260246000fd5b600082612ddb57612ddb612db6565b500490565b81810381811115610e6157610e61612d89565b600060208284031215612e0557600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612e4b57612e4b612e0c565b604052919050565b600067ffffffffffffffff80841115612e6e57612e6e612e0c565b8360051b6020612e7f818301612e22565b868152918501918181019036841115612e9757600080fd5b865b84811015612f1c57803586811115612eb15760008081fd5b8801601f3681830112612ec45760008081fd5b813588811115612ed657612ed6612e0c565b612ee7818301601f19168801612e22565b91508082523687828501011115612efe5760008081fd5b80878401888401376000908201870152845250918301918301612e99565b50979650505050505050565b634e487b7160e01b600052603260045260246000fd5b80820180821115610e6157610e61612d89565b600060018201612f6357612f63612d89565b5060010190565b600060208284031215612f7c57600080fd5b81518015158114610e4757600080fd5b600060ff831680612f9f57612f9f612db6565b8060ff84160691505092915050565b60ff8281168282160390811115610e6157610e61612d89565b634e487b7160e01b600052602160045260246000fd5b60005b83811015612ff8578181015183820152602001612fe0565b50506000910152565b60008251613013818460208701612fdd565b9190910192915050565b602081526000825180602084015261303c816040850160208701612fdd565b601f01601f1916919091016040019291505056fea2646970667358221220dc7c7551c830c38afdece1edca1021a7cdd65727a786d19cf62197738b756b5564736f6c63430008130033"; + "0x60a06040523480156200001157600080fd5b506040516200320138038062003201833981016040819052620000349162000103565b60016000556200004433620000b1565b6001600160a01b0381166200009f5760405162461bcd60e51b815260206004820152601460248201527f546f6b656e2063616e6e6f74206265207a65726f000000000000000000000000604482015260640160405180910390fd5b6001600160a01b031660805262000135565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602082840312156200011657600080fd5b81516001600160a01b03811681146200012e57600080fd5b9392505050565b6080516130866200017b600039600081816101e1015281816104730152818161049d01528181610761015281816108650152818161090d0152610a5201526130866000f3fe608060405234801561001057600080fd5b50600436106100d35760003560e01c80639366452c11610081578063f301af421161005b578063f301af42146101bb578063f7c618c1146101dc578063f8738c251461020357600080fd5b80639366452c14610182578063e525310514610195578063f2fde38b146101a857600080fd5b80636d46379b116100b25780636d46379b14610146578063715018a6146101695780638da5cb5b1461017157600080fd5b8062501e28146100d85780631ce92be5146100ed57806341f891a414610100575b600080fd5b6100eb6100e6366004612c03565b61025a565b005b6100eb6100fb366004612c6b565b61051c565b61012961010e366004612c9e565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610159610154366004612cb9565b6105cd565b604051901515815260200161013d565b6100eb610667565b6001546001600160a01b0316610129565b6100eb610190366004612d13565b61067b565b6100eb6101a3366004612d4e565b61096e565b6100eb6101b6366004612c9e565b610ac9565b6101ce6101c9366004612d70565b610b59565b60405190815260200161013d565b6101297f000000000000000000000000000000000000000000000000000000000000000081565b61023a610211366004612d70565b600360208190526000918252604090912080546001820154600283015492909301549092919084565b60408051948552602085019390935291830152606082015260800161013d565b610262610b7a565b600083815260036020526040902060018101546102c65760405162461bcd60e51b815260206004820152601060248201527f526577617264206e6f7420666f756e640000000000000000000000000000000060448201526064015b60405180910390fd5b336000908152600460205260408120546001600160a01b03166102e95733610303565b336000908152600460205260409020546001600160a01b03165b604080516001600160a01b038316602082015260029181019190915290915060009060600160405160208183030381529060405280519060200120905060006103528460010154838888610bd3565b90506000670de0b6b3a764000085600301548361036f9190612d9f565b6103799190612dcc565b905080856000015410156103cf5760405162461bcd60e51b815260206004820152601d60248201527f436c61696d20756e6465722d66756e6465642062792066756e6465722e00000060448201526064016102bd565b600088815260036020908152604080832086845260040190915290205460ff161561043c5760405162461bcd60e51b815260206004820152600f60248201527f416c726561647920636c61696d6564000000000000000000000000000000000060448201526064016102bd565b60008381526004860160205260409020805460ff191660011790558454610464908290612de0565b855561049a6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168583610c70565b877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b03167fceea116ca90ae38b5f3bcd7482763d0bdd5915faed2146d37b1e3bcd1ea425378460405161050091815260200190565b60405180910390a450505050506105176001600055565b505050565b610524610d19565b6001600160a01b0382161580159061054457506001600160a01b03811615155b6105905760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420616464726573732070726f7669646564000000000000000060448201526064016102bd565b6001600160a01b03908116600090815260046020526040902080549190921673ffffffffffffffffffffffffffffffffffffffff19909116179055565b60008481526003602090815260408083206001015481516001600160a01b038816818501526002818401528251808203840181526060909101909252815191909201208183036106225760009250505061065f565b600087815260036020908152604080832084845260040190915290205460ff1615801561065a5750600061065883838888610bd3565b115b925050505b949350505050565b61066f610d19565b6106796000610d73565b565b610683610d19565b836106d05760405162461bcd60e51b815260206004820152601a60248201527f4d65726b6c6520726f6f742063616e6e6f74206265207a65726f00000000000060448201526064016102bd565b60008381526003602052604090206001810154156107305760405162461bcd60e51b815260206004820152601e60248201527f4d65726b6c6520726f6f742077617320616c726561647920706f73746564000060448201526064016102bd565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156107b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d49190612df3565b90506000871180156107e65750808711155b6108585760405162461bcd60e51b815260206004820152602660248201527f496e76616c696420616d6f756e74206f7220696e73756666696369656e74206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016102bd565b61088d6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308a610dd2565b8682556001820186905560028201849055826108b188670de0b6b3a7640000612d9f565b6108bb9190612dcc565b6003830155600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace01859055604080518881526020810187905290810185905286907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169033907f4993e379e2a0a87975314480436d8f2de32d291a64892cb63cdb0839d09044369060600160405180910390a450505050505050565b610976610d19565b600082815260036020526040902060028101544210156109d85760405162461bcd60e51b815260206004820152601c60248201527f52657761726473206d6179206e6f742062652077697468647261776e0000000060448201526064016102bd565b8054821115610a295760405162461bcd60e51b815260206004820152601460248201527f496e73756666696369656e742062616c616e636500000000000000000000000060448201526064016102bd565b81816000016000828254610a3d9190612de0565b9182905550825550610a796001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163384610c70565b6001808201546040805186815260208101869052908101929092529033907f210aece5a2bb3ac8bbec4d3bd83444123ef037a899b89d617e735799f983e6b39060600160405180910390a3505050565b610ad1610d19565b6001600160a01b038116610b4d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102bd565b610b5681610d73565b50565b60028181548110610b6957600080fd5b600091825260209091200154905081565b600260005403610bcc5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016102bd565b6002600055565b600080610c14610c0f86604051602001610bef91815260200190565b60408051601f19818403018152919052610c098688612e53565b89610e29565b610e4e565b905060005b8151811015610c6657818181518110610c3457610c34612f28565b016020015160f81c610c4884610100612d9f565b610c529190612f3e565b925080610c5e81612f51565b915050610c19565b5050949350505050565b6040516001600160a01b0383166024820152604481018290526105179084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610e67565b6001546001600160a01b031633146106795760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102bd565b600180546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6040516001600160a01b0380851660248301528316604482015260648101829052610e239085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610cb5565b50505050565b60606000610e3685610f4f565b9050610e43818585610f81565b9150505b9392505050565b6060610e61610e5c8361189d565b611959565b92915050565b6000610ebc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611a8e9092919063ffffffff16565b9050805160001480610edd575080806020019051810190610edd9190612f6a565b6105175760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016102bd565b60608180519060200120604051602001610f6b91815260200190565b6040516020818303038152906040529050919050565b60606000845111610fd45760405162461bcd60e51b815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b6579000000000000000000000060448201526064016102bd565b6000610fdf84611a9d565b90506000610fec86611b8c565b905060008460405160200161100391815260200190565b60405160208183030381529060405290506000805b845181101561182e57600085828151811061103557611035612f28565b6020026020010151905084518311156110b65760405162461bcd60e51b815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e67746800000000000000000000000000000000000060648201526084016102bd565b826000036111555780518051602091820120604051611104926110de92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b6111505760405162461bcd60e51b815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f74206861736800000060448201526064016102bd565b611278565b8051516020116111f1578051805160209182012060405161117f926110de92910190815260200190565b6111505760405162461bcd60e51b815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c20686173680000000000000000000000000000000000000000000000000060648201526084016102bd565b8051845160208087019190912082519190920120146112785760405162461bcd60e51b815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f652068617368000000000000000000000000000000000000000000000000000060648201526084016102bd565b61128460106001612f3e565b8160200151510361143157845183036113c95760006112c082602001516010815181106112b3576112b3612f28565b6020026020010151611959565b905060008151116113395760405162461bcd60e51b815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e636829000000000060648201526084016102bd565b600187516113479190612de0565b83146113bb5760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e63682900000000000060648201526084016102bd565b9650610e4795505050505050565b60008584815181106113dd576113dd612f28565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061140857611408612f28565b6020026020010151905061141b81611bef565b9550611428600186612f3e565b9450505061181b565b6002816020015151036117ad57600061144982611c14565b905060008160008151811061146057611460612f28565b016020015160f81c90506000611477600283612f8c565b611482906002612fae565b90506000611493848360ff16611c38565b905060006114a18a89611c38565b905060006114af8383611c6e565b9050808351146115275760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b657900000000000060648201526084016102bd565b60ff85166002148061153c575060ff85166003145b156116e257808251146115b75760405162461bcd60e51b815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e64657200000060648201526084016102bd565b60006115d388602001516001815181106112b3576112b3612f28565b9050600081511161164c5760405162461bcd60e51b815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c656166290000000000000060648201526084016102bd565b60018d5161165a9190612de0565b89146116ce5760405162461bcd60e51b815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c65616629000000000000000060648201526084016102bd565b9c50610e479b505050505050505050505050565b60ff851615806116f5575060ff85166001145b1561173457611721876020015160018151811061171457611714612f28565b6020026020010151611bef565b995061172d818a612f3e565b98506117a2565b60405162461bcd60e51b815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e20707265666978000000000000000000000000000060648201526084016102bd565b50505050505061181b565b60405162461bcd60e51b815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f646500000000000000000000000000000000000000000000000060648201526084016102bd565b508061182681612f51565b915050611018565b5060405162461bcd60e51b815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e747300000000000000000000000000000000000000000000000000000060648201526084016102bd565b6040805180820190915260008082526020820152600082511161193b5760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f206265606482015269206465636f6461626c6560b01b608482015260a4016102bd565b50604080518082019091528151815260209182019181019190915290565b6060600080600061196985611d05565b91945092509050600081600181111561198457611984612fc7565b146119f75760405162461bcd60e51b815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d0000000000000060648201526084016102bd565b611a018284612f3e565b855114611a765760405162461bcd60e51b815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e64657200000000000000000000000060648201526084016102bd565b611a85856020015184846125c7565b95945050505050565b606061065f8484600085612668565b805160609060008167ffffffffffffffff811115611abd57611abd612e0c565b604051908082528060200260200182016040528015611b0257816020015b6040805180820190915260608082526020820152815260200190600190039081611adb5790505b50905060005b82811015611b84576040518060400160405280868381518110611b2d57611b2d612f28565b60200260200101518152602001611b5c878481518110611b4f57611b4f612f28565b602002602001015161274f565b815250828281518110611b7157611b71612f28565b6020908102919091010152600101611b08565b509392505050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015611be4578060011b82018184015160001a8060041c8253600f811660018301535050600101611bb6565b509295945050505050565b60606020826000015110611c0b57611c0682611959565b610e61565b610e6182612762565b6060610e61611c3383602001516000815181106112b3576112b3612f28565b611b8c565b606082518210611c575750604080516020810190915260008152610e61565b610e478383848651611c699190612de0565b612778565b60008060008351855110611c83578351611c86565b84515b90505b8082108015611cf55750838281518110611ca557611ca5612f28565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858381518110611ce457611ce4612f28565b01602001516001600160f81b031916145b15611b8457816001019150611c89565b600080600080846000015111611d965760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f206265606482015269206465636f6461626c6560b01b608482015260a4016102bd565b6020840151805160001a607f8111611dbb5760006001600094509450945050506125c0565b60b78111611f65576000611dd0608083612de0565b905080876000015111611e715760405162461bcd60e51b815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a4016102bd565b6001838101516001600160f81b0319169082141580611eba57507f80000000000000000000000000000000000000000000000000000000000000006001600160f81b0319821610155b611f525760405162461bcd60e51b815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a4016102bd565b50600195509350600092506125c0915050565b60bf8111612233576000611f7a60b783612de0565b90508087600001511161201b5760405162461bcd60e51b815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a4016102bd565b60018301516001600160f81b03191660008190036120c75760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a4016102bd565b600184015160088302610100031c603781116121715760405162461bcd60e51b815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a4016102bd565b61217b8184612f3e565b8951116122165760405162461bcd60e51b815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a4016102bd565b612221836001612f3e565b97509550600094506125c09350505050565b60f781116122fa57600061224860c083612de0565b9050808760000151116122e95760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a4016102bd565b6001955093508492506125c0915050565b600061230760f783612de0565b9050808760000151116123a85760405162461bcd60e51b815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a4016102bd565b60018301516001600160f81b03191660008190036124545760405162461bcd60e51b815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a4016102bd565b600184015160088302610100031c603781116124fe5760405162461bcd60e51b815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a4016102bd565b6125088184612f3e565b8951116125a35760405162461bcd60e51b815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a4016102bd565b6125ae836001612f3e565b97509550600194506125c09350505050565b9193909250565b606060008267ffffffffffffffff8111156125e4576125e4612e0c565b6040519080825280601f01601f19166020018201604052801561260e576020820181803683370190505b50905082600003612620579050610e47565b600061262c8587612f3e565b90506020820160005b8581101561264d578281015182820152602001612635565b8581111561265c576000868301525b50919695505050505050565b6060824710156126e05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016102bd565b600080866001600160a01b031685876040516126fc9190613001565b60006040518083038185875af1925050503d8060008114612739576040519150601f19603f3d011682016040523d82523d6000602084013e61273e565b606091505b509150915061065a878383876128e4565b6060610e6161275d8361189d565b61295d565b6060610e618260200151600084600001516125c7565b60608182601f0110156127cd5760405162461bcd60e51b815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016102bd565b82828401101561281f5760405162461bcd60e51b815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016102bd565b818301845110156128725760405162461bcd60e51b815260206004820152601160248201527f736c6963655f6f75744f66426f756e647300000000000000000000000000000060448201526064016102bd565b60608215801561289157604051915060008252602082016040526128db565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156128ca5780518352602092830192016128b2565b5050858452601f01601f1916604052505b50949350505050565b6060831561295357825160000361294c576001600160a01b0385163b61294c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102bd565b508161065f565b61065f8383612b8d565b6060600080600061296d85611d05565b91945092509050600181600181111561298857612988612fc7565b146129fb5760405162461bcd60e51b815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d000000000000000060648201526084016102bd565b8451612a078385612f3e565b14612a7a5760405162461bcd60e51b815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e646572000000000000000000000000000060648201526084016102bd565b6040805160208082526104208201909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081612a935790505090506000845b8751811015612b8157600080612b066040518060400160405280858d60000151612aea9190612de0565b8152602001858d60200151612aff9190612f3e565b9052611d05565b509150915060405180604001604052808383612b229190612f3e565b8152602001848c60200151612b379190612f3e565b815250858581518110612b4c57612b4c612f28565b6020908102919091010152612b62600185612f3e565b9350612b6e8183612f3e565b612b789084612f3e565b92505050612ac0565b50815295945050505050565b815115612b9d5781518083602001fd5b8060405162461bcd60e51b81526004016102bd919061301d565b60008083601f840112612bc957600080fd5b50813567ffffffffffffffff811115612be157600080fd5b6020830191508360208260051b8501011115612bfc57600080fd5b9250929050565b600080600060408486031215612c1857600080fd5b83359250602084013567ffffffffffffffff811115612c3657600080fd5b612c4286828701612bb7565b9497909650939450505050565b80356001600160a01b0381168114612c6657600080fd5b919050565b60008060408385031215612c7e57600080fd5b612c8783612c4f565b9150612c9560208401612c4f565b90509250929050565b600060208284031215612cb057600080fd5b610e4782612c4f565b60008060008060608587031215612ccf57600080fd5b84359350612cdf60208601612c4f565b9250604085013567ffffffffffffffff811115612cfb57600080fd5b612d0787828801612bb7565b95989497509550505050565b600080600080600060a08688031215612d2b57600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060408385031215612d6157600080fd5b50508035926020909101359150565b600060208284031215612d8257600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e6157610e61612d89565b634e487b7160e01b600052601260045260246000fd5b600082612ddb57612ddb612db6565b500490565b81810381811115610e6157610e61612d89565b600060208284031215612e0557600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612e4b57612e4b612e0c565b604052919050565b600067ffffffffffffffff80841115612e6e57612e6e612e0c565b8360051b6020612e7f818301612e22565b868152918501918181019036841115612e9757600080fd5b865b84811015612f1c57803586811115612eb15760008081fd5b8801601f3681830112612ec45760008081fd5b813588811115612ed657612ed6612e0c565b612ee7818301601f19168801612e22565b91508082523687828501011115612efe5760008081fd5b80878401888401376000908201870152845250918301918301612e99565b50979650505050505050565b634e487b7160e01b600052603260045260246000fd5b80820180821115610e6157610e61612d89565b600060018201612f6357612f63612d89565b5060010190565b600060208284031215612f7c57600080fd5b81518015158114610e4757600080fd5b600060ff831680612f9f57612f9f612db6565b8060ff84160691505092915050565b60ff8281168282160390811115610e6157610e61612d89565b634e487b7160e01b600052602160045260246000fd5b60005b83811015612ff8578181015183820152602001612fe0565b50506000910152565b60008251613013818460208701612fdd565b9190910192915050565b602081526000825180602084015261303c816040850160208701612fdd565b601f01601f1916919091016040019291505056fea2646970667358221220ef586eb6a714f1d80c54375ad6c7029882b499d015fab7a74b47a02e7dd863e864736f6c63430008130033"; type SonneMerkleDistributorConstructorParams = | [signer?: Signer] diff --git a/crosschain-rewards/src/types/factories/contracts/TestContract__factory.ts b/crosschain-rewards/src/types/factories/contracts/TestContract__factory.ts index efea733..6ca316e 100644 --- a/crosschain-rewards/src/types/factories/contracts/TestContract__factory.ts +++ b/crosschain-rewards/src/types/factories/contracts/TestContract__factory.ts @@ -73,7 +73,7 @@ const _abi = [ ] as const; const _bytecode = - "0x608060405234801561001057600080fd5b50600080546001600160a01b031916331790556101eb806100326000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806340c10f19146100465780638da5cb5b1461005b578063ce7c2ac21461008b575b600080fd5b610059610054366004610169565b6100b9565b005b60005461006e906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100ab610099366004610193565b60026020526000908152604090205481565b604051908152602001610082565b6000546001600160a01b03163314610131576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6f6e6c79206f776e657200000000000000000000000000000000000000000000604482015260640160405180910390fd5b6001600160a01b03909116600090815260026020526040902055565b80356001600160a01b038116811461016457600080fd5b919050565b6000806040838503121561017c57600080fd5b6101858361014d565b946020939093013593505050565b6000602082840312156101a557600080fd5b6101ae8261014d565b939250505056fea26469706673582212208dcaa8a6bac2133b4ee3bb5229f81bd750a6ea72c493b58bdeb45f146444f24f64736f6c63430008130033"; + "0x608060405234801561001057600080fd5b50600080546001600160a01b031916331790556101eb806100326000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806340c10f19146100465780638da5cb5b1461005b578063ce7c2ac21461008b575b600080fd5b610059610054366004610169565b6100b9565b005b60005461006e906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100ab610099366004610193565b60026020526000908152604090205481565b604051908152602001610082565b6000546001600160a01b03163314610131576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6f6e6c79206f776e657200000000000000000000000000000000000000000000604482015260640160405180910390fd5b6001600160a01b03909116600090815260026020526040902055565b80356001600160a01b038116811461016457600080fd5b919050565b6000806040838503121561017c57600080fd5b6101858361014d565b946020939093013593505050565b6000602082840312156101a557600080fd5b6101ae8261014d565b939250505056fea2646970667358221220429c2e093e3b23f539e02130c089b9f7df480691ccb60abd07356bc8686f7da164736f6c63430008130033"; type TestContractConstructorParams = | [signer?: Signer] diff --git a/crosschain-rewards/src/types/factories/contracts/mocks/ERC20Mock__factory.ts b/crosschain-rewards/src/types/factories/contracts/mocks/ERC20Mock__factory.ts index b988179..84e3239 100644 --- a/crosschain-rewards/src/types/factories/contracts/mocks/ERC20Mock__factory.ts +++ b/crosschain-rewards/src/types/factories/contracts/mocks/ERC20Mock__factory.ts @@ -402,7 +402,7 @@ const _abi = [ ] as const; const _bytecode = - "0x608060405260405162001038380380620010388339810160408190526200002691620001f4565b8383600362000036838262000315565b50600462000045828262000315565b5050506200005a82826200006460201b60201c565b5050505062000409565b6001600160a01b038216620000bf5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640160405180910390fd5b8060026000828254620000d39190620003e1565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200015757600080fd5b81516001600160401b03808211156200017457620001746200012f565b604051601f8301601f19908116603f011681019082821181831017156200019f576200019f6200012f565b81604052838152602092508683858801011115620001bc57600080fd5b600091505b83821015620001e05785820183015181830184015290820190620001c1565b600093810190920192909252949350505050565b600080600080608085870312156200020b57600080fd5b84516001600160401b03808211156200022357600080fd5b620002318883890162000145565b955060208701519150808211156200024857600080fd5b50620002578782880162000145565b604087015190945090506001600160a01b03811681146200027757600080fd5b6060959095015193969295505050565b600181811c908216806200029c57607f821691505b602082108103620002bd57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200012a57600081815260208120601f850160051c81016020861015620002ec5750805b601f850160051c820191505b818110156200030d57828155600101620002f8565b505050505050565b81516001600160401b038111156200033157620003316200012f565b620003498162000342845462000287565b84620002c3565b602080601f831160018114620003815760008415620003685750858301515b600019600386901b1c1916600185901b1785556200030d565b600085815260208120601f198616915b82811015620003b25788860151825594840194600190910190840162000391565b5085821015620003d15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808201808211156200040357634e487b7160e01b600052601160045260246000fd5b92915050565b610c1f80620004196000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806340c10f19116100975780639dc29fac116100665780639dc29fac146101ee578063a457c2d714610201578063a9059cbb14610214578063dd62ed3e1461022757600080fd5b806340c10f191461019757806356189cb4146101aa57806370a08231146101bd57806395d89b41146101e657600080fd5b8063222f5be0116100d3578063222f5be01461014d57806323b872dd14610162578063313ce56714610175578063395093511461018457600080fd5b806306fdde03146100fa578063095ea7b31461011857806318160ddd1461013b575b600080fd5b610102610260565b60405161010f9190610a69565b60405180910390f35b61012b610126366004610ad3565b6102f2565b604051901515815260200161010f565b6002545b60405190815260200161010f565b61016061015b366004610afd565b61030c565b005b61012b610170366004610afd565b61031c565b6040516012815260200161010f565b61012b610192366004610ad3565b610340565b6101606101a5366004610ad3565b61037f565b6101606101b8366004610afd565b61038d565b61013f6101cb366004610b39565b6001600160a01b031660009081526020819052604090205490565b610102610398565b6101606101fc366004610ad3565b6103a7565b61012b61020f366004610ad3565b6103b1565b61012b610222366004610ad3565b610460565b61013f610235366004610b5b565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60606003805461026f90610b8e565b80601f016020809104026020016040519081016040528092919081815260200182805461029b90610b8e565b80156102e85780601f106102bd576101008083540402835291602001916102e8565b820191906000526020600020905b8154815290600101906020018083116102cb57829003601f168201915b5050505050905090565b60003361030081858561046e565b60019150505b92915050565b6103178383836105c6565b505050565b60003361032a8582856107b5565b6103358585856105c6565b506001949350505050565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909190610300908290869061037a908790610bc8565b61046e565b6103898282610841565b5050565b61031783838361046e565b60606004805461026f90610b8e565b6103898282610900565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909190838110156104535760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610335828686840361046e565b6000336103008185856105c6565b6001600160a01b0383166104e95760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161044a565b6001600160a01b0382166105655760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161044a565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166106425760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161044a565b6001600160a01b0382166106be5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161044a565b6001600160a01b0383166000908152602081905260409020548181101561074d5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161044a565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35b50505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146107af57818110156108345760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161044a565b6107af848484840361046e565b6001600160a01b0382166108975760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161044a565b80600260008282546108a99190610bc8565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b03821661097c5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161044a565b6001600160a01b03821660009081526020819052604090205481811015610a0b5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161044a565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b600060208083528351808285015260005b81811015610a9657858101830151858201604001528201610a7a565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610ace57600080fd5b919050565b60008060408385031215610ae657600080fd5b610aef83610ab7565b946020939093013593505050565b600080600060608486031215610b1257600080fd5b610b1b84610ab7565b9250610b2960208501610ab7565b9150604084013590509250925092565b600060208284031215610b4b57600080fd5b610b5482610ab7565b9392505050565b60008060408385031215610b6e57600080fd5b610b7783610ab7565b9150610b8560208401610ab7565b90509250929050565b600181811c90821680610ba257607f821691505b602082108103610bc257634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561030657634e487b7160e01b600052601160045260246000fdfea26469706673582212201bd79807b074c69802c5d51c090fc5644c9e1ff923d2c0cc61bd8ca1655ecc6b64736f6c63430008130033"; + "0x608060405260405162001038380380620010388339810160408190526200002691620001f4565b8383600362000036838262000315565b50600462000045828262000315565b5050506200005a82826200006460201b60201c565b5050505062000409565b6001600160a01b038216620000bf5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640160405180910390fd5b8060026000828254620000d39190620003e1565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200015757600080fd5b81516001600160401b03808211156200017457620001746200012f565b604051601f8301601f19908116603f011681019082821181831017156200019f576200019f6200012f565b81604052838152602092508683858801011115620001bc57600080fd5b600091505b83821015620001e05785820183015181830184015290820190620001c1565b600093810190920192909252949350505050565b600080600080608085870312156200020b57600080fd5b84516001600160401b03808211156200022357600080fd5b620002318883890162000145565b955060208701519150808211156200024857600080fd5b50620002578782880162000145565b604087015190945090506001600160a01b03811681146200027757600080fd5b6060959095015193969295505050565b600181811c908216806200029c57607f821691505b602082108103620002bd57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200012a57600081815260208120601f850160051c81016020861015620002ec5750805b601f850160051c820191505b818110156200030d57828155600101620002f8565b505050505050565b81516001600160401b038111156200033157620003316200012f565b620003498162000342845462000287565b84620002c3565b602080601f831160018114620003815760008415620003685750858301515b600019600386901b1c1916600185901b1785556200030d565b600085815260208120601f198616915b82811015620003b25788860151825594840194600190910190840162000391565b5085821015620003d15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808201808211156200040357634e487b7160e01b600052601160045260246000fd5b92915050565b610c1f80620004196000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806340c10f19116100975780639dc29fac116100665780639dc29fac146101ee578063a457c2d714610201578063a9059cbb14610214578063dd62ed3e1461022757600080fd5b806340c10f191461019757806356189cb4146101aa57806370a08231146101bd57806395d89b41146101e657600080fd5b8063222f5be0116100d3578063222f5be01461014d57806323b872dd14610162578063313ce56714610175578063395093511461018457600080fd5b806306fdde03146100fa578063095ea7b31461011857806318160ddd1461013b575b600080fd5b610102610260565b60405161010f9190610a69565b60405180910390f35b61012b610126366004610ad3565b6102f2565b604051901515815260200161010f565b6002545b60405190815260200161010f565b61016061015b366004610afd565b61030c565b005b61012b610170366004610afd565b61031c565b6040516012815260200161010f565b61012b610192366004610ad3565b610340565b6101606101a5366004610ad3565b61037f565b6101606101b8366004610afd565b61038d565b61013f6101cb366004610b39565b6001600160a01b031660009081526020819052604090205490565b610102610398565b6101606101fc366004610ad3565b6103a7565b61012b61020f366004610ad3565b6103b1565b61012b610222366004610ad3565b610460565b61013f610235366004610b5b565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60606003805461026f90610b8e565b80601f016020809104026020016040519081016040528092919081815260200182805461029b90610b8e565b80156102e85780601f106102bd576101008083540402835291602001916102e8565b820191906000526020600020905b8154815290600101906020018083116102cb57829003601f168201915b5050505050905090565b60003361030081858561046e565b60019150505b92915050565b6103178383836105c6565b505050565b60003361032a8582856107b5565b6103358585856105c6565b506001949350505050565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909190610300908290869061037a908790610bc8565b61046e565b6103898282610841565b5050565b61031783838361046e565b60606004805461026f90610b8e565b6103898282610900565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909190838110156104535760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610335828686840361046e565b6000336103008185856105c6565b6001600160a01b0383166104e95760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161044a565b6001600160a01b0382166105655760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161044a565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166106425760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161044a565b6001600160a01b0382166106be5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161044a565b6001600160a01b0383166000908152602081905260409020548181101561074d5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161044a565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35b50505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146107af57818110156108345760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161044a565b6107af848484840361046e565b6001600160a01b0382166108975760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161044a565b80600260008282546108a99190610bc8565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b03821661097c5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161044a565b6001600160a01b03821660009081526020819052604090205481811015610a0b5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161044a565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b600060208083528351808285015260005b81811015610a9657858101830151858201604001528201610a7a565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610ace57600080fd5b919050565b60008060408385031215610ae657600080fd5b610aef83610ab7565b946020939093013593505050565b600080600060608486031215610b1257600080fd5b610b1b84610ab7565b9250610b2960208501610ab7565b9150604084013590509250925092565b600060208284031215610b4b57600080fd5b610b5482610ab7565b9392505050565b60008060408385031215610b6e57600080fd5b610b7783610ab7565b9150610b8560208401610ab7565b90509250929050565b600181811c90821680610ba257607f821691505b602082108103610bc257634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561030657634e487b7160e01b600052601160045260246000fdfea26469706673582212209e19ad38ce29b225385a3de7e111a7bde9b8210b4603edc1e9f764313bf7e32d64736f6c63430008130033"; type ERC20MockConstructorParams = | [signer?: Signer] diff --git a/crosschain-rewards/src/types/factories/contracts/mocks/ERC20WithPermitMock__factory.ts b/crosschain-rewards/src/types/factories/contracts/mocks/ERC20WithPermitMock__factory.ts index 4af430d..957c55c 100644 --- a/crosschain-rewards/src/types/factories/contracts/mocks/ERC20WithPermitMock__factory.ts +++ b/crosschain-rewards/src/types/factories/contracts/mocks/ERC20WithPermitMock__factory.ts @@ -385,7 +385,7 @@ const _abi = [ ] as const; const _bytecode = - "0x608060405234801561001057600080fd5b50604080518082018252600f81526e115490cc8c15da5d1a14195c9b5a5d608a1b6020918201528151808301835260018152603160f81b9082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527f8e8dfca995c0dc34242d28254fc73b766b49c42aaa21d5cfed4a98afa719e9db818401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a0808301919091528351808303909101815260c09091019092528151910120600355610a80806100f66000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806370a0823111610097578063cd3b3ccd11610066578063cd3b3ccd14610272578063d4d92b1414610343578063d505accf14610358578063dd62ed3e1461036b57600080fd5b806370a08231146101e35780637ecebe001461020357806395d89b4114610223578063a9059cbb1461025f57600080fd5b806323b872dd116100d357806323b872dd1461018657806330adf81f14610199578063313ce567146101c05780633644e515146101da57600080fd5b806306fdde03146100fa578063095ea7b31461014c57806318160ddd1461016f575b600080fd5b6101366040518060400160405280600f81526020017f4552433230576974685065726d6974000000000000000000000000000000000081525081565b6040516101439190610809565b60405180910390f35b61015f61015a366004610873565b610396565b6040519015158152602001610143565b61017860005481565b604051908152602001610143565b61015f61019436600461089d565b6103ad565b6101787f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6101c8601281565b60405160ff9091168152602001610143565b61017860035481565b6101786101f13660046108d9565b60016020526000908152604090205481565b6101786102113660046108d9565b60046020526000908152604090205481565b6101366040518060400160405280600781526020017f455243323057500000000000000000000000000000000000000000000000000081525081565b61015f61026d366004610873565b610414565b6101786102803660046108f4565b6003546001600160a01b039485166000818152600460209081526040918290205482517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452969097166060830152608082019490945260a081019490945260c0808501929092528251808503909201825260e08401835281519185019190912061190160f01b61010085015261010284019190915261012280840191909152815180840390910181526101429092019052805191012090565b610356610351366004610873565b610421565b005b610356610366366004610936565b61042f565b6101786103793660046109a9565b600260209081526000928352604080842090915290825290205481565b60006103a3338484610653565b5060015b92915050565b6001600160a01b03831660009081526002602090815260408083203384529091528120546103db90836106b5565b6001600160a01b038516600090815260026020908152604080832033845290915290205561040a8484846106c8565b5060019392505050565b60006103a33384846106c8565b61042b828261076e565b5050565b428410156104845760405162461bcd60e51b815260206004820152600760248201527f455850495245440000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6003546001600160a01b038816600090815260046020526040812080549192917f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b9190876104d783610a0b565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e0016040516020818303038152906040528051906020012060405160200161055092919061190160f01b81526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa1580156105bb573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906105f15750886001600160a01b0316816001600160a01b0316145b61063d5760405162461bcd60e51b815260206004820152601160248201527f494e56414c49445f5349474e4154555245000000000000000000000000000000604482015260640161047b565b610648898989610653565b505050505050505050565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60006106c18284610a24565b9392505050565b6001600160a01b0383166000908152600160205260409020546106eb90826106b5565b6001600160a01b03808516600090815260016020526040808220939093559084168152205461071a90826107fd565b6001600160a01b0380841660008181526001602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906106a89085815260200190565b60005461077b90826107fd565b60009081556001600160a01b0383168152600160205260409020546107a090826107fd565b6001600160a01b0383166000818152600160205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906107f19085815260200190565b60405180910390a35050565b60006106c18284610a37565b600060208083528351808285015260005b818110156108365785810183015185820160400152820161081a565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461086e57600080fd5b919050565b6000806040838503121561088657600080fd5b61088f83610857565b946020939093013593505050565b6000806000606084860312156108b257600080fd5b6108bb84610857565b92506108c960208501610857565b9150604084013590509250925092565b6000602082840312156108eb57600080fd5b6106c182610857565b6000806000806080858703121561090a57600080fd5b61091385610857565b935061092160208601610857565b93969395505050506040820135916060013590565b600080600080600080600060e0888a03121561095157600080fd5b61095a88610857565b965061096860208901610857565b95506040880135945060608801359350608088013560ff8116811461098c57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156109bc57600080fd5b6109c583610857565b91506109d360208401610857565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060018201610a1d57610a1d6109dc565b5060010190565b818103818111156103a7576103a76109dc565b808201808211156103a7576103a76109dc56fea26469706673582212201e653ce71dff08717abe509456574325d7b1b27980476c5e3d8c8873e4f3a83a64736f6c63430008130033"; + "0x608060405234801561001057600080fd5b50604080518082018252600f81526e115490cc8c15da5d1a14195c9b5a5d608a1b6020918201528151808301835260018152603160f81b9082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527f8e8dfca995c0dc34242d28254fc73b766b49c42aaa21d5cfed4a98afa719e9db818401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a0808301919091528351808303909101815260c09091019092528151910120600355610a80806100f66000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806370a0823111610097578063cd3b3ccd11610066578063cd3b3ccd14610272578063d4d92b1414610343578063d505accf14610358578063dd62ed3e1461036b57600080fd5b806370a08231146101e35780637ecebe001461020357806395d89b4114610223578063a9059cbb1461025f57600080fd5b806323b872dd116100d357806323b872dd1461018657806330adf81f14610199578063313ce567146101c05780633644e515146101da57600080fd5b806306fdde03146100fa578063095ea7b31461014c57806318160ddd1461016f575b600080fd5b6101366040518060400160405280600f81526020017f4552433230576974685065726d6974000000000000000000000000000000000081525081565b6040516101439190610809565b60405180910390f35b61015f61015a366004610873565b610396565b6040519015158152602001610143565b61017860005481565b604051908152602001610143565b61015f61019436600461089d565b6103ad565b6101787f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6101c8601281565b60405160ff9091168152602001610143565b61017860035481565b6101786101f13660046108d9565b60016020526000908152604090205481565b6101786102113660046108d9565b60046020526000908152604090205481565b6101366040518060400160405280600781526020017f455243323057500000000000000000000000000000000000000000000000000081525081565b61015f61026d366004610873565b610414565b6101786102803660046108f4565b6003546001600160a01b039485166000818152600460209081526040918290205482517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452969097166060830152608082019490945260a081019490945260c0808501929092528251808503909201825260e08401835281519185019190912061190160f01b61010085015261010284019190915261012280840191909152815180840390910181526101429092019052805191012090565b610356610351366004610873565b610421565b005b610356610366366004610936565b61042f565b6101786103793660046109a9565b600260209081526000928352604080842090915290825290205481565b60006103a3338484610653565b5060015b92915050565b6001600160a01b03831660009081526002602090815260408083203384529091528120546103db90836106b5565b6001600160a01b038516600090815260026020908152604080832033845290915290205561040a8484846106c8565b5060019392505050565b60006103a33384846106c8565b61042b828261076e565b5050565b428410156104845760405162461bcd60e51b815260206004820152600760248201527f455850495245440000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6003546001600160a01b038816600090815260046020526040812080549192917f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b9190876104d783610a0b565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e0016040516020818303038152906040528051906020012060405160200161055092919061190160f01b81526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa1580156105bb573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906105f15750886001600160a01b0316816001600160a01b0316145b61063d5760405162461bcd60e51b815260206004820152601160248201527f494e56414c49445f5349474e4154555245000000000000000000000000000000604482015260640161047b565b610648898989610653565b505050505050505050565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60006106c18284610a24565b9392505050565b6001600160a01b0383166000908152600160205260409020546106eb90826106b5565b6001600160a01b03808516600090815260016020526040808220939093559084168152205461071a90826107fd565b6001600160a01b0380841660008181526001602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906106a89085815260200190565b60005461077b90826107fd565b60009081556001600160a01b0383168152600160205260409020546107a090826107fd565b6001600160a01b0383166000818152600160205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906107f19085815260200190565b60405180910390a35050565b60006106c18284610a37565b600060208083528351808285015260005b818110156108365785810183015185820160400152820161081a565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461086e57600080fd5b919050565b6000806040838503121561088657600080fd5b61088f83610857565b946020939093013593505050565b6000806000606084860312156108b257600080fd5b6108bb84610857565b92506108c960208501610857565b9150604084013590509250925092565b6000602082840312156108eb57600080fd5b6106c182610857565b6000806000806080858703121561090a57600080fd5b61091385610857565b935061092160208601610857565b93969395505050506040820135916060013590565b600080600080600080600060e0888a03121561095157600080fd5b61095a88610857565b965061096860208901610857565b95506040880135945060608801359350608088013560ff8116811461098c57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156109bc57600080fd5b6109c583610857565b91506109d360208401610857565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060018201610a1d57610a1d6109dc565b5060010190565b818103818111156103a7576103a76109dc565b808201808211156103a7576103a76109dc56fea2646970667358221220fb56726ae9333a02c589ce46411db2a96e1e04fdf3bb1fd40dd4adbfed10972b64736f6c63430008130033"; type ERC20WithPermitMockConstructorParams = | [signer?: Signer]