Contract
0x2787cc20e5ecb4bf1bfb79eae284201027683179
10
Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
MultipleMerkleDistributor
Compiler Version
v0.8.7+commit.e28d00a7
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Trees proofs. * * The proofs can be generated using the JavaScript library * https://github.com/miguelmota/merkletreejs[merkletreejs]. * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled. * * See `test/utils/cryptography/MerkleProof.test.js` for some examples. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { bytes32 proofElement = proof[i]; if (computedHash <= proofElement) { // Hash(current computed hash + current element of the proof) computedHash = keccak256(abi.encodePacked(computedHash, proofElement)); } else { // Hash(current element of the proof + current computed hash) computedHash = keccak256(abi.encodePacked(proofElement, computedHash)); } } // Check if the computed hash (root) is equal to the provided root return computedHash == root; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.6.0; import "../../contracts/interfaces/IMultipleMerkleDistributor.sol"; abstract contract $IMultipleMerkleDistributor is IMultipleMerkleDistributor { constructor() {} }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.6.0; import "../../contracts/interfaces/IRewardEscrow.sol"; contract $VestingEntries { constructor() {} } abstract contract $IRewardEscrow is IRewardEscrow { constructor() {} }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.6.0; import "../contracts/MultipleMerkleDistributor.sol"; contract $MultipleMerkleDistributor is MultipleMerkleDistributor { constructor(address _owner, address _token, address _rewardEscrow) MultipleMerkleDistributor(_owner, _token, _rewardEscrow) {} }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.6.0; import "../../contracts/utils/Owned.sol"; contract $Owned is Owned { constructor(address _owner) Owned(_owner) {} }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.0; // Allows anyone to claim a token if they exist in a merkle root. interface IMultipleMerkleDistributor { /// @notice data structure for aggregating multiple claims struct Claims { uint256 index; address account; uint256 amount; bytes32[] merkleProof; uint256 epoch; } /// @notice event is triggered whenever a call to `claim` succeeds event Claimed( uint256 index, address account, uint256 amount, uint256 epoch ); /// @notice event is triggered whenever a merkle root is set event MerkleRootModified(uint256 epoch); /// @return escrow for tokens claimed function rewardEscrow() external view returns (address); /// @return token to be distributed (KWENTA) function token() external view returns (address); // @return the merkle root of the merkle tree containing account balances available to claim function merkleRoots(uint256) external view returns (bytes32); /// @notice determine if indexed claim has been claimed /// @param index: used for claim managment /// @param epoch: distribution index number /// @return true if indexed claim has been claimed function isClaimed(uint256 index, uint256 epoch) external view returns (bool); /// @notice attempt to claim as `account` and escrow KWENTA for `account` /// @param index: used for merkle tree managment and verification /// @param account: address used for escrow entry /// @param amount: $KWENTA amount to be escrowed /// @param merkleProof: off-chain generated proof of merkle tree inclusion /// @param epoch: distribution index number function claim( uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof, uint256 epoch ) external; /// @notice function that aggregates multiple claims /// @param claims: array of valid claims function claimMultiple(Claims[] calldata claims) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library VestingEntries { struct VestingEntry { uint64 endTime; uint256 escrowAmount; uint256 duration; } struct VestingEntryWithID { uint64 endTime; uint256 escrowAmount; uint256 entryID; } } interface IRewardEscrow { // Views function getKwentaAddress() external view returns (address); function balanceOf(address account) external view returns (uint256); function numVestingEntries(address account) external view returns (uint256); function totalEscrowedAccountBalance(address account) external view returns (uint256); function totalVestedAccountBalance(address account) external view returns (uint256); function getVestingQuantity(address account, uint256[] calldata entryIDs) external view returns (uint256, uint256); function getVestingSchedules( address account, uint256 index, uint256 pageSize ) external view returns (VestingEntries.VestingEntryWithID[] memory); function getAccountVestingEntryIDs( address account, uint256 index, uint256 pageSize ) external view returns (uint256[] memory); function getVestingEntryClaimable(address account, uint256 entryID) external view returns (uint256, uint256); function getVestingEntry(address account, uint256 entryID) external view returns ( uint64, uint256, uint256 ); // Mutative functions function vest(uint256[] calldata entryIDs) external; function createEscrowEntry( address beneficiary, uint256 deposit, uint256 duration ) external; function appendVestingEntry( address account, uint256 quantity, uint256 duration ) external; function stakeEscrow(uint256 _amount) external; function unstakeEscrow(uint256 _amount) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import "./utils/Owned.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "./interfaces/IRewardEscrow.sol"; import "./interfaces/IMultipleMerkleDistributor.sol"; /// @title Kwenta MultipleMerkleDistributor /// @author JaredBorders and JChiaramonte7 /// @notice Facilitates trading incentives distribution over multiple periods. contract MultipleMerkleDistributor is IMultipleMerkleDistributor, Owned { /// @notice escrow for tokens claimed address public immutable override rewardEscrow; /// @notice token to be distributed (KWENTA) address public immutable override token; /// @notice an epoch to merkle root mapping /// of a merkle tree containing account balances available to claim mapping(uint256 => bytes32) public override merkleRoots; /// @notice an epoch to packed array of claimed booleans mapping mapping(uint256 => mapping(uint256 => uint256)) private claimedBitMaps; /// @notice set addresses for deployed rewardEscrow and KWENTA. /// Establish merkle root for verification /// @param _owner: designated owner of this contract /// @param _token: address of erc20 token to be distributed /// @param _rewardEscrow: address of kwenta escrow for tokens claimed constructor( address _owner, address _token, address _rewardEscrow ) Owned(_owner) { token = _token; rewardEscrow = _rewardEscrow; } /// @notice modify merkle root for existing distribution epoch function setMerkleRootForEpoch(bytes32 merkleRoot, uint256 epoch) external onlyOwner { merkleRoots[epoch] = merkleRoot; emit MerkleRootModified(epoch); } /// @notice determine if indexed claim has been claimed /// @param index: used for claim managment /// @param epoch: distribution index to check /// @return true if indexed claim has been claimed function isClaimed(uint256 index, uint256 epoch) public view override returns (bool) { uint256 claimedWordIndex = index / 256; uint256 claimedBitIndex = index % 256; uint256 claimedWord = claimedBitMaps[epoch][claimedWordIndex]; uint256 mask = (1 << claimedBitIndex); return claimedWord & mask == mask; } /// @notice set claimed status for indexed claim to true /// @param index: used for claim managment /// @param epoch: distribution index to check function _setClaimed(uint256 index, uint256 epoch) private { uint256 claimedWordIndex = index / 256; uint256 claimedBitIndex = index % 256; claimedBitMaps[epoch][claimedWordIndex] = claimedBitMaps[epoch][claimedWordIndex] | (1 << claimedBitIndex); } /// @notice attempt to claim as `account` and escrow KWENTA for `account` /// @param index: used for merkle tree managment and verification /// @param account: address used for escrow entry /// @param amount: $KWENTA amount to be escrowed /// @param merkleProof: off-chain generated proof of merkle tree inclusion /// @param epoch: distribution index to check function claim( uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof, uint256 epoch ) public override { require( !isClaimed(index, epoch), "MultipleMerkleDistributor: Drop already claimed." ); // verify the merkle proof bytes32 node = keccak256(abi.encodePacked(index, account, amount)); require( MerkleProof.verify(merkleProof, merkleRoots[epoch], node), "MultipleMerkleDistributor: Invalid proof." ); // mark it claimed and send the token to RewardEscrow _setClaimed(index, epoch); IERC20(token).approve(rewardEscrow, amount); IRewardEscrow(rewardEscrow).createEscrowEntry( account, amount, 52 weeks ); emit Claimed(index, account, amount, epoch); } /// @notice function that aggregates multiple claims /// @param claims: array of valid claims function claimMultiple(Claims[] calldata claims) external override { uint256 cacheLength = claims.length; for (uint256 i = 0; i < cacheLength; ) { claim( claims[i].index, claims[i].account, claims[i].amount, claims[i].merkleProof, claims[i].epoch ); unchecked { i++; } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // https://docs.synthetix.io/contracts/source/contracts/owned contract Owned { address public owner; address public nominatedOwner; constructor(address _owner) { require(_owner != address(0), "Owner address cannot be 0"); owner = _owner; emit OwnerChanged(address(0), _owner); } function nominateNewOwner(address _owner) external onlyOwner { nominatedOwner = _owner; emit OwnerNominated(_owner); } function acceptOwnership() external { require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership"); emit OwnerChanged(owner, nominatedOwner); owner = nominatedOwner; nominatedOwner = address(0); } modifier onlyOwner { _onlyOwner(); _; } function _onlyOwner() private view { require(msg.sender == owner, "Only the contract owner may perform this action"); } event OwnerNominated(address newOwner); event OwnerChanged(address oldOwner, address newOwner); }
{ "optimizer": { "enabled": true, "runs": 1000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_rewardEscrow","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"MerkleRootModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"epoch","type":"uint256"}],"internalType":"struct IMultipleMerkleDistributor.Claims[]","name":"claims","type":"tuple[]"}],"name":"claimMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"isClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"merkleRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardEscrow","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"setMerkleRootForEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c060405234801561001057600080fd5b50604051610e4d380380610e4d83398101604081905261002f9161011d565b826001600160a01b03811661008a5760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f74206265203000000000000000604482015260640160405180910390fd5b600080546001600160a01b0319166001600160a01b03831690811782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1506001600160601b0319606092831b811660a052911b1660805250610160565b80516001600160a01b038116811461011857600080fd5b919050565b60008060006060848603121561013257600080fd5b61013b84610101565b925061014960208501610101565b915061015760408501610101565b90509250925092565b60805160601c60a05160601c610cad6101a0600039600081816101e4015261065f0152600081816101610152818161063001526107250152610cad6000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c8063a430be6c11610081578063d0b55e8c1161005b578063d0b55e8c146101a9578063f364c90c146101bc578063fc0c546a146101df57600080fd5b8063a430be6c1461015c578063ab5943db14610183578063c02bb7ba1461019657600080fd5b806371c5ecb1116100b257806371c5ecb11461011357806379ba5097146101415780638da5cb5b1461014957600080fd5b80631627540c146100ce57806353a47bb7146100e3575b600080fd5b6100e16100dc366004610a5f565b610206565b005b6001546100f6906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610133610121366004610b07565b60026020526000908152604090205481565b60405190815260200161010a565b6100e161026f565b6000546100f6906001600160a01b031681565b6100f67f000000000000000000000000000000000000000000000000000000000000000081565b6100e1610191366004610a81565b610373565b6100e16101a4366004610b20565b610471565b6100e16101b7366004610ae5565b6107db565b6101cf6101ca366004610ae5565b610832565b604051901515815260200161010a565b6100f67f000000000000000000000000000000000000000000000000000000000000000081565b61020e61087d565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229060200160405180910390a150565b6001546001600160a01b031633146102f45760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527f2063616e20616363657074206f776e657273686970000000000000000000000060648201526084015b60405180910390fd5b600054600154604080516001600160a01b0393841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b03841617909155169055565b8060005b8181101561046b5761046384848381811061039457610394610c61565b90506020028101906103a69190610bda565b358585848181106103b9576103b9610c61565b90506020028101906103cb9190610bda565b6103dc906040810190602001610a5f565b8686858181106103ee576103ee610c61565b90506020028101906104009190610bda565b6040013587878681811061041657610416610c61565b90506020028101906104289190610bda565b610436906060810190610b90565b89898881811061044857610448610c61565b905060200281019061045a9190610bda565b60800135610471565b600101610377565b50505050565b61047b8682610832565b156104ee5760405162461bcd60e51b815260206004820152603060248201527f4d756c7469706c654d65726b6c654469737472696275746f723a2044726f702060448201527f616c726561647920636c61696d65642e0000000000000000000000000000000060648201526084016102eb565b60408051602081018890526bffffffffffffffffffffffff19606088901b16918101919091526054810185905260009060740160405160208183030381529060405280519060200120905061058484848080602002602001604051908101604052809392919081815260200183836020028082843760009201829052508781526002602052604090205492508591506108ff9050565b6105f65760405162461bcd60e51b815260206004820152602960248201527f4d756c7469706c654d65726b6c654469737472696275746f723a20496e76616c60448201527f69642070726f6f662e000000000000000000000000000000000000000000000060648201526084016102eb565b61060087836109ae565b6040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b390604401602060405180830381600087803b1580156106a357600080fd5b505af11580156106b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106db9190610ac3565b506040517fa0416ed30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790526301dfe20060448301527f0000000000000000000000000000000000000000000000000000000000000000169063a0416ed390606401600060405180830381600087803b15801561076957600080fd5b505af115801561077d573d6000803e3d6000fd5b5050604080518a81526001600160a01b038a166020820152908101889052606081018590527fd9cb1e2714d65a111c0f20f060176ad657496bd47a3de04ec7c3d4ca232112ac9250608001905060405180910390a150505050505050565b6107e361087d565b60008181526002602052604090819020839055517f7835b531ba83151bc18466c9b0ab4b168056cb422098530a34952b03f87ba519906108269083815260200190565b60405180910390a15050565b60008061084161010085610bfa565b9050600061085161010086610c37565b60009485526003602090815260408087209487529390529190932054600190911b908116149392505050565b6000546001600160a01b031633146108fd5760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201527f6f726d207468697320616374696f6e000000000000000000000000000000000060648201526084016102eb565b565b600081815b85518110156109a357600086828151811061092157610921610c61565b60200260200101519050808311610963576040805160208101859052908101829052606001604051602081830303815290604052805190602001209250610990565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b508061099b81610c0e565b915050610904565b509092149392505050565b60006109bc61010084610bfa565b905060006109cc61010085610c37565b6000938452600360209081526040808620948652939052919092208054600190921b90911790555050565b80356001600160a01b0381168114610a0e57600080fd5b919050565b60008083601f840112610a2557600080fd5b50813567ffffffffffffffff811115610a3d57600080fd5b6020830191508360208260051b8501011115610a5857600080fd5b9250929050565b600060208284031215610a7157600080fd5b610a7a826109f7565b9392505050565b60008060208385031215610a9457600080fd5b823567ffffffffffffffff811115610aab57600080fd5b610ab785828601610a13565b90969095509350505050565b600060208284031215610ad557600080fd5b81518015158114610a7a57600080fd5b60008060408385031215610af857600080fd5b50508035926020909101359150565b600060208284031215610b1957600080fd5b5035919050565b60008060008060008060a08789031215610b3957600080fd5b86359550610b49602088016109f7565b945060408701359350606087013567ffffffffffffffff811115610b6c57600080fd5b610b7889828a01610a13565b979a9699509497949695608090950135949350505050565b6000808335601e19843603018112610ba757600080fd5b83018035915067ffffffffffffffff821115610bc257600080fd5b6020019150600581901b3603821315610a5857600080fd5b60008235609e19833603018112610bf057600080fd5b9190910192915050565b600082610c0957610c09610c4b565b500490565b6000600019821415610c3057634e487b7160e01b600052601160045260246000fd5b5060010190565b600082610c4657610c46610c4b565b500690565b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fdfea2646970667358221220ee9c5e8a65d2752478613b7515ae8466d3313fcb7f267efebb8c6b351b316f9464736f6c63430008070033000000000000000000000000e029c32d412972c5f3d107da6d6ecf8f1c1e788c000000000000000000000000920cf626a271321c151d027030d5d08af699456b0000000000000000000000001066a8eb3d90af0ad3f89839b974658577e75be2
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e029c32d412972c5f3d107da6d6ecf8f1c1e788c000000000000000000000000920cf626a271321c151d027030d5d08af699456b0000000000000000000000001066a8eb3d90af0ad3f89839b974658577e75be2
-----Decoded View---------------
Arg [0] : _owner (address): 0xe029c32d412972C5F3D107DA6d6eCF8F1C1E788C
Arg [1] : _token (address): 0x920Cf626a271321C151D027030D5d08aF699456b
Arg [2] : _rewardEscrow (address): 0x1066A8eB3d90Af0Ad3F89839b974658577e75BE2
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000e029c32d412972c5f3d107da6d6ecf8f1c1e788c
Arg [1] : 000000000000000000000000920cf626a271321c151d027030d5d08af699456b
Arg [2] : 0000000000000000000000001066a8eb3d90af0ad3f89839b974658577e75be2
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.