@levxdao/ve
Version:
VE and Gauge Voting for NFTs
322 lines • 35.2 kB
JSON
{
"address": "0x271f3CDAB424563BC727e92DE1948Cb2db8B155f",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_ve",
"type": "address"
},
{
"internalType": "address",
"name": "_token",
"type": "address"
},
{
"internalType": "address",
"name": "_discountToken",
"type": "address"
},
{
"internalType": "uint256",
"name": "_minDuration",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_maxBoost",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_deadline",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "discount",
"type": "uint256"
},
{
"indexed": true,
"internalType": "uint256",
"name": "locktime",
"type": "uint256"
}
],
"name": "CreateLock",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "discount",
"type": "uint256"
}
],
"name": "IncreaseAmount",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "addr",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "penaltyRate",
"type": "uint256"
}
],
"name": "Withdraw",
"type": "event"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "duration",
"type": "uint256"
}
],
"name": "createLock",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "duration",
"type": "uint256"
}
],
"name": "createLockDiscounted",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "deadline",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "discountToken",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "increaseAmount",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "increaseAmountDiscounted",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "maxBoost",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "minDuration",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "token",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "ve",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "withdraw",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"transactionHash": "0x0cf432aa1a4e2601a45f28cdb9e185d3fd54d68bb147a18732bf693cc71a7032",
"receipt": {
"to": null,
"from": "0x5b8C253517b6Bd003369173109693B01cb6841B5",
"contractAddress": "0x271f3CDAB424563BC727e92DE1948Cb2db8B155f",
"transactionIndex": 185,
"gasUsed": "662237",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x92ed3bc67678eb7a8b5dbf19a03bbbbef783647482c74258d937f308cfd72f56",
"transactionHash": "0x0cf432aa1a4e2601a45f28cdb9e185d3fd54d68bb147a18732bf693cc71a7032",
"logs": [],
"blockNumber": 14903252,
"cumulativeGasUsed": "12924805",
"status": 1,
"byzantium": true
},
"args": [
"0x77D3d884FeA1E389150a26D4569b20ebA284A86d",
"0xf474E526ADe9aD2CC2B66ffCE528B1A51B91FCdC",
"0xb8b07d0f2990ddd5b99b6db59dd8356ca2b1302d",
18921600,
10,
1655596800
],
"solcInputHash": "e47e3caa7a97fd9ed213c8c8516f216a",
"metadata": "{\"compiler\":{\"version\":\"0.8.14+commit.80d49f37\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_ve\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_discountToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_minDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxBoost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_deadline\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"discount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"locktime\",\"type\":\"uint256\"}],\"name\":\"CreateLock\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"discount\",\"type\":\"uint256\"}],\"name\":\"IncreaseAmount\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"penaltyRate\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"}],\"name\":\"createLock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"}],\"name\":\"createLockDiscounted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deadline\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"discountToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"increaseAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"increaseAmountDiscounted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxBoost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minDuration\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ve\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BoostedVotingEscrowDelegate.sol\":\"BoostedVotingEscrowDelegate\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/BoostedVotingEscrowDelegate.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.14;\\n\\nimport \\\"./VotingEscrowDelegate.sol\\\";\\n\\ncontract BoostedVotingEscrowDelegate is VotingEscrowDelegate {\\n uint256 public immutable minDuration;\\n uint256 public immutable maxBoost;\\n uint256 public immutable deadline;\\n\\n constructor(\\n address _ve,\\n address _token,\\n address _discountToken,\\n uint256 _minDuration,\\n uint256 _maxBoost,\\n uint256 _deadline\\n ) VotingEscrowDelegate(_ve, _token, _discountToken) {\\n minDuration = _minDuration;\\n maxBoost = _maxBoost;\\n deadline = _deadline;\\n }\\n\\n function _createLock(\\n uint256 amountToken,\\n uint256 duration,\\n bool discounted\\n ) internal override {\\n require(block.timestamp < deadline, \\\"BVED: EXPIRED\\\");\\n require(duration >= minDuration, \\\"BVED: DURATION_TOO_SHORT\\\");\\n\\n super._createLock(amountToken, duration, discounted);\\n }\\n\\n function _increaseAmount(uint256 amountToken, bool discounted) internal override {\\n require(block.timestamp < deadline, \\\"BVED: EXPIRED\\\");\\n\\n super._increaseAmount(amountToken, discounted);\\n }\\n\\n function _getAmounts(uint256 amount, uint256 duration)\\n internal\\n view\\n override\\n returns (uint256 amountVE, uint256 amountToken)\\n {\\n amountVE = (amount * maxBoost * duration) / _maxDuration;\\n amountToken = amount;\\n }\\n}\\n\",\"keccak256\":\"0x6e4fd37646fc44d2cc24e3b17bddc1a2de77f044121aeff2cf1cb32a924fd834\",\"license\":\"UNLICENSED\"},\"contracts/VotingEscrowDelegate.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.14;\\n\\nimport \\\"./interfaces/IVotingEscrowDelegate.sol\\\";\\nimport \\\"./interfaces/IVotingEscrow.sol\\\";\\nimport \\\"./interfaces/INFT.sol\\\";\\n\\nabstract contract VotingEscrowDelegate is IVotingEscrowDelegate {\\n address public immutable ve;\\n address public immutable token;\\n address public immutable discountToken;\\n\\n uint256 internal immutable _maxDuration;\\n uint256 internal immutable _interval;\\n\\n event CreateLock(address indexed account, uint256 amount, uint256 discount, uint256 indexed locktime);\\n event IncreaseAmount(address indexed account, uint256 amount, uint256 discount);\\n\\n constructor(\\n address _ve,\\n address _token,\\n address _discountToken\\n ) {\\n ve = _ve;\\n token = _token;\\n discountToken = _discountToken;\\n\\n _maxDuration = IVotingEscrow(_ve).maxDuration();\\n _interval = IVotingEscrow(ve).interval();\\n }\\n\\n modifier eligibleForDiscount {\\n require(INFT(discountToken).balanceOf(msg.sender) > 0, \\\"VED: DISCOUNT_TOKEN_NOT_OWNED\\\");\\n _;\\n }\\n\\n function createLockDiscounted(uint256 amount, uint256 duration) external eligibleForDiscount {\\n _createLock(amount, duration, true);\\n }\\n\\n function createLock(uint256 amount, uint256 duration) external {\\n _createLock(amount, duration, false);\\n }\\n\\n function _createLock(\\n uint256 amount,\\n uint256 duration,\\n bool discounted\\n ) internal virtual {\\n require(duration <= _maxDuration, \\\"VED: DURATION_TOO_LONG\\\");\\n\\n uint256 unlockTime = ((block.timestamp + duration) / _interval) * _interval; // rounded down to a multiple of interval\\n uint256 _duration = unlockTime - block.timestamp;\\n (uint256 amountVE, uint256 amountToken) = _getAmounts(amount, _duration);\\n if (discounted) {\\n amountVE = (amountVE * 100) / 90;\\n }\\n\\n emit CreateLock(msg.sender, amountVE, amountVE - amountToken, unlockTime);\\n IVotingEscrow(ve).createLockFor(msg.sender, amountVE, amountVE - amountToken, _duration);\\n }\\n\\n function increaseAmountDiscounted(uint256 amount) external eligibleForDiscount {\\n _increaseAmount(amount, true);\\n }\\n\\n function increaseAmount(uint256 amount) external {\\n _increaseAmount(amount, false);\\n }\\n\\n function _increaseAmount(uint256 amount, bool discounted) internal virtual {\\n uint256 unlockTime = IVotingEscrow(ve).unlockTime(msg.sender);\\n require(unlockTime > 0, \\\"VED: LOCK_NOT_FOUND\\\");\\n\\n (uint256 amountVE, uint256 amountToken) = _getAmounts(amount, unlockTime - block.timestamp);\\n if (discounted) {\\n amountVE = (amountVE * 100) / 90;\\n }\\n\\n emit IncreaseAmount(msg.sender, amountVE, amountVE - amountToken);\\n IVotingEscrow(ve).increaseAmountFor(msg.sender, amountVE, amountVE - amountToken);\\n }\\n\\n function _getAmounts(uint256 amount, uint256 duration)\\n internal\\n view\\n virtual\\n returns (uint256 amountVE, uint256 amountToken);\\n\\n function withdraw(address, uint256) external virtual override {\\n // Empty\\n }\\n}\\n\",\"keccak256\":\"0xd12a2a8f7b94e4aa59f1802d592aedd5a55fdc57aae2d550f810fc1c6a08b2c8\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/INFT.sol\":{\"content\":\"// SPDX-License-Identifier: WTFPL\\npragma solidity ^0.8.0;\\n\\ninterface INFT {\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n function mint(\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n function mintBatch(\\n address to,\\n uint256[] calldata tokenIds,\\n bytes calldata data\\n ) external;\\n\\n function burn(\\n uint256 tokenId,\\n uint256 label,\\n bytes32 data\\n ) external;\\n}\\n\",\"keccak256\":\"0xc83595af93e7a8388326fde207d30ab71ef7c661c366a65da9f918a099918141\",\"license\":\"WTFPL\"},\"contracts/interfaces/IVotingEscrow.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.0;\\n\\ninterface IVotingEscrow {\\n event SetMigrator(address indexed account);\\n event SetDelegate(address indexed account, bool isDelegate);\\n event Deposit(\\n address indexed provider,\\n uint256 value,\\n uint256 discount,\\n uint256 indexed unlockTime,\\n int128 indexed _type,\\n uint256 ts\\n );\\n event Cancel(address indexed provider, uint256 value, uint256 discount, uint256 penaltyRate, uint256 ts);\\n event Withdraw(address indexed provider, uint256 value, uint256 discount, uint256 ts);\\n event Migrate(address indexed provider, uint256 value, uint256 discount, uint256 ts);\\n event Supply(uint256 prevSupply, uint256 supply);\\n\\n function interval() external view returns (uint256);\\n\\n function maxDuration() external view returns (uint256);\\n\\n function token() external view returns (address);\\n\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n\\n function migrator() external view returns (address);\\n\\n function isDelegate(address account) external view returns (bool);\\n\\n function supply() external view returns (uint256);\\n\\n function migrated(address account) external view returns (bool);\\n\\n function delegateAt(address account, uint256 index) external view returns (address);\\n\\n function locked(address account)\\n external\\n view\\n returns (\\n int128 amount,\\n int128 discount,\\n uint256 start,\\n uint256 end\\n );\\n\\n function epoch() external view returns (uint256);\\n\\n function pointHistory(uint256 epoch)\\n external\\n view\\n returns (\\n int128 bias,\\n int128 slope,\\n uint256 ts,\\n uint256 blk\\n );\\n\\n function userPointHistory(address account, uint256 epoch)\\n external\\n view\\n returns (\\n int128 bias,\\n int128 slope,\\n uint256 ts,\\n uint256 blk\\n );\\n\\n function userPointEpoch(address account) external view returns (uint256);\\n\\n function slopeChanges(uint256 epoch) external view returns (int128);\\n\\n function delegateLength(address addr) external view returns (uint256);\\n\\n function getLastUserSlope(address addr) external view returns (int128);\\n\\n function getCheckpointTime(address _addr, uint256 _idx) external view returns (uint256);\\n\\n function unlockTime(address _addr) external view returns (uint256);\\n\\n function setMigrator(address _migrator) external;\\n\\n function setDelegate(address account, bool _isDelegate) external;\\n\\n function checkpoint() external;\\n\\n function depositFor(address _addr, uint256 _value) external;\\n\\n function createLockFor(\\n address _addr,\\n uint256 _value,\\n uint256 _discount,\\n uint256 _duration\\n ) external;\\n\\n function createLock(uint256 _value, uint256 _duration) external;\\n\\n function increaseAmountFor(\\n address _addr,\\n uint256 _value,\\n uint256 _discount\\n ) external;\\n\\n function increaseAmount(uint256 _value) external;\\n\\n function increaseUnlockTime(uint256 _duration) external;\\n\\n function cancel() external;\\n\\n function withdraw() external;\\n\\n function migrate() external;\\n\\n function balanceOf(address addr) external view returns (uint256);\\n\\n function balanceOf(address addr, uint256 _t) external view returns (uint256);\\n\\n function balanceOfAt(address addr, uint256 _block) external view returns (uint256);\\n\\n function totalSupply() external view returns (uint256);\\n\\n function totalSupply(uint256 t) external view returns (uint256);\\n\\n function totalSupplyAt(uint256 _block) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x3ac00d3de6b34a0c5cb777b5e9477af3982061f7e9021848dc662508f1cf0f1b\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/IVotingEscrowDelegate.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.0;\\n\\ninterface IVotingEscrowDelegate {\\n event Withdraw(address indexed addr, uint256 amount, uint256 penaltyRate);\\n\\n function withdraw(address addr, uint256 penaltyRate) external;\\n}\\n\",\"keccak256\":\"0x6ba70000f8e426991d384d100a94596b815599f7698c49a95ffac88fbebab8a1\",\"license\":\"UNLICENSED\"}},\"version\":1}",
"bytecode": "0x61018060405234801561001157600080fd5b50604051610d55380380610d5583398101604081905261003091610157565b6001600160a01b03808716608081905281871660a05290851660c05260408051636db5c8fd60e01b81529051889288928892636db5c8fd916004808201926020929091908290030181865afa15801561008d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100b191906101b6565b60e081815250506080516001600160a01b031663947a36fb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061011c91906101b6565b61010052505050610120929092526101405261016052506101cf915050565b80516001600160a01b038116811461015257600080fd5b919050565b60008060008060008060c0878903121561017057600080fd5b6101798761013b565b95506101876020880161013b565b94506101956040880161013b565b9350606087015192506080870151915060a087015190509295509295509295565b6000602082840312156101c857600080fd5b5051919050565b60805160a05160c05160e05161010051610120516101405161016051610adc6102796000396000818161010c015281816104070152610470015260008181610141015261095401526000818161016801526104cf015260006107b4015260008181610749015261092f0152600081816101c801528181610249015261033e0152600061020101526000818160c801528181610565015281816106a901526108830152610adc6000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c806383e995a11161007157806383e995a11461018a578063b52c05fe1461019d578063e8103656146101b0578063ea61226c146101c3578063f3fef3a3146101ea578063fc0c546a146101fc57600080fd5b806315456eba146100ae5780631f850716146100c357806329dcb0cf1461010757806337090c2f1461013c5780635671576114610163575b600080fd5b6100c16100bc366004610994565b610223565b005b6100ea7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61012e7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016100fe565b61012e7f000000000000000000000000000000000000000000000000000000000000000081565b61012e7f000000000000000000000000000000000000000000000000000000000000000081565b6100c16101983660046109ad565b610231565b6100c16101ab3660046109ad565b61031a565b6100c16101be366004610994565b610326565b6100ea7f000000000000000000000000000000000000000000000000000000000000000081565b6100c16101f83660046109cf565b5050565b6100ea7f000000000000000000000000000000000000000000000000000000000000000081565b61022e816000610405565b50565b6040516370a0823160e01b81523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610298573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102bc9190610a07565b1161030e5760405162461bcd60e51b815260206004820152601d60248201527f5645443a20444953434f554e545f544f4b454e5f4e4f545f4f574e454400000060448201526064015b60405180910390fd5b6101f88282600161046e565b6101f88282600061046e565b6040516370a0823160e01b81523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561038d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103b19190610a07565b116103fe5760405162461bcd60e51b815260206004820152601d60248201527f5645443a20444953434f554e545f544f4b454e5f4e4f545f4f574e45440000006044820152606401610305565b61022e8160015b7f000000000000000000000000000000000000000000000000000000000000000042106104645760405162461bcd60e51b815260206004820152600d60248201526c109591510e8811561412549151609a1b6044820152606401610305565b6101f8828261054d565b7f000000000000000000000000000000000000000000000000000000000000000042106104cd5760405162461bcd60e51b815260206004820152600d60248201526c109591510e8811561412549151609a1b6044820152606401610305565b7f000000000000000000000000000000000000000000000000000000000000000082101561053d5760405162461bcd60e51b815260206004820152601860248201527f425645443a204455524154494f4e5f544f4f5f53484f525400000000000000006044820152606401610305565b610548838383610747565b505050565b6040516376b467b760e01b81523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906376b467b790602401602060405180830381865afa1580156105b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d89190610a07565b9050600081116106205760405162461bcd60e51b81526020600482015260136024820152721591510e881313d0d2d7d393d517d193d55391606a1b6044820152606401610305565b600080610636856106314286610a36565b61092a565b91509150831561065a57605a61064d836064610a4d565b6106579190610a6c565b91505b337f837403c20d32bb2d2c7f2a3d9a0e648369645c6fb8985cc0c5c9ddb0bacc5115836106878482610a36565b6040805192835260208301919091520160405180910390a26001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166399742dc633846106da8582610a36565b6040516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091526044820152606401600060405180830381600087803b15801561072857600080fd5b505af115801561073c573d6000803e3d6000fd5b505050505050505050565b7f00000000000000000000000000000000000000000000000000000000000000008211156107b05760405162461bcd60e51b81526020600482015260166024820152755645443a204455524154494f4e5f544f4f5f4c4f4e4760501b6044820152606401610305565b60007f0000000000000000000000000000000000000000000000000000000000000000806107de8542610a8e565b6107e89190610a6c565b6107f29190610a4d565b905060006108004283610a36565b905060008061080f878461092a565b91509150841561083357605a610826836064610a4d565b6108309190610a6c565b91505b83337f133e6f671a17d15981c6269ce9d49d721e64d359ebfd0787e56bbe73c15ba014846108618582610a36565b6040805192835260208301919091520160405180910390a36001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663a6db822b33846108b48582610a36565b6040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260648101869052608401600060405180830381600087803b15801561090957600080fd5b505af115801561091d573d6000803e3d6000fd5b5050505050505050505050565b6000807f0000000000000000000000000000000000000000000000000000000000000000836109797f000000000000000000000000000000000000000000000000000000000000000087610a4d565b6109839190610a4d565b61098d9190610a6c565b9492505050565b6000602082840312156109a657600080fd5b5035919050565b600080604083850312156109c057600080fd5b50508035926020909101359150565b600080604083850312156109e257600080fd5b82356001600160a01b03811681146109f957600080fd5b946020939093013593505050565b600060208284031215610a1957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082821015610a4857610a48610a20565b500390565b6000816000190483118215151615610a6757610a67610a20565b500290565b600082610a8957634e487b7160e01b600052601260045260246000fd5b500490565b60008219821115610aa157610aa1610a20565b50019056fea264697066735822122051feb31f8ddca64c9a99e69b702dfae8358faad8e5b4885aa834d36ae0ee49c664736f6c634300080e0033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a95760003560e01c806383e995a11161007157806383e995a11461018a578063b52c05fe1461019d578063e8103656146101b0578063ea61226c146101c3578063f3fef3a3146101ea578063fc0c546a146101fc57600080fd5b806315456eba146100ae5780631f850716146100c357806329dcb0cf1461010757806337090c2f1461013c5780635671576114610163575b600080fd5b6100c16100bc366004610994565b610223565b005b6100ea7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61012e7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016100fe565b61012e7f000000000000000000000000000000000000000000000000000000000000000081565b61012e7f000000000000000000000000000000000000000000000000000000000000000081565b6100c16101983660046109ad565b610231565b6100c16101ab3660046109ad565b61031a565b6100c16101be366004610994565b610326565b6100ea7f000000000000000000000000000000000000000000000000000000000000000081565b6100c16101f83660046109cf565b5050565b6100ea7f000000000000000000000000000000000000000000000000000000000000000081565b61022e816000610405565b50565b6040516370a0823160e01b81523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610298573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102bc9190610a07565b1161030e5760405162461bcd60e51b815260206004820152601d60248201527f5645443a20444953434f554e545f544f4b454e5f4e4f545f4f574e454400000060448201526064015b60405180910390fd5b6101f88282600161046e565b6101f88282600061046e565b6040516370a0823160e01b81523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561038d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103b19190610a07565b116103fe5760405162461bcd60e51b815260206004820152601d60248201527f5645443a20444953434f554e545f544f4b454e5f4e4f545f4f574e45440000006044820152606401610305565b61022e8160015b7f000000000000000000000000000000000000000000000000000000000000000042106104645760405162461bcd60e51b815260206004820152600d60248201526c109591510e8811561412549151609a1b6044820152606401610305565b6101f8828261054d565b7f000000000000000000000000000000000000000000000000000000000000000042106104cd5760405162461bcd60e51b815260206004820152600d60248201526c109591510e8811561412549151609a1b6044820152606401610305565b7f000000000000000000000000000000000000000000000000000000000000000082101561053d5760405162461bcd60e51b815260206004820152601860248201527f425645443a204455524154494f4e5f544f4f5f53484f525400000000000000006044820152606401610305565b610548838383610747565b505050565b6040516376b467b760e01b81523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906376b467b790602401602060405180830381865afa1580156105b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d89190610a07565b9050600081116106205760405162461bcd60e51b81526020600482015260136024820152721591510e881313d0d2d7d393d517d193d55391606a1b6044820152606401610305565b600080610636856106314286610a36565b61092a565b91509150831561065a57605a61064d836064610a4d565b6106579190610a6c565b91505b337f837403c20d32bb2d2c7f2a3d9a0e648369645c6fb8985cc0c5c9ddb0bacc5115836106878482610a36565b6040805192835260208301919091520160405180910390a26001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166399742dc633846106da8582610a36565b6040516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091526044820152606401600060405180830381600087803b15801561072857600080fd5b505af115801561073c573d6000803e3d6000fd5b505050505050505050565b7f00000000000000000000000000000000000000000000000000000000000000008211156107b05760405162461bcd60e51b81526020600482015260166024820152755645443a204455524154494f4e5f544f4f5f4c4f4e4760501b6044820152606401610305565b60007f0000000000000000000000000000000000000000000000000000000000000000806107de8542610a8e565b6107e89190610a6c565b6107f29190610a4d565b905060006108004283610a36565b905060008061080f878461092a565b91509150841561083357605a610826836064610a4d565b6108309190610a6c565b91505b83337f133e6f671a17d15981c6269ce9d49d721e64d359ebfd0787e56bbe73c15ba014846108618582610a36565b6040805192835260208301919091520160405180910390a36001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663a6db822b33846108b48582610a36565b6040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260648101869052608401600060405180830381600087803b15801561090957600080fd5b505af115801561091d573d6000803e3d6000fd5b5050505050505050505050565b6000807f0000000000000000000000000000000000000000000000000000000000000000836109797f000000000000000000000000000000000000000000000000000000000000000087610a4d565b6109839190610a4d565b61098d9190610a6c565b9492505050565b6000602082840312156109a657600080fd5b5035919050565b600080604083850312156109c057600080fd5b50508035926020909101359150565b600080604083850312156109e257600080fd5b82356001600160a01b03811681146109f957600080fd5b946020939093013593505050565b600060208284031215610a1957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082821015610a4857610a48610a20565b500390565b6000816000190483118215151615610a6757610a67610a20565b500290565b600082610a8957634e487b7160e01b600052601260045260246000fd5b500490565b60008219821115610aa157610aa1610a20565b50019056fea264697066735822122051feb31f8ddca64c9a99e69b702dfae8358faad8e5b4885aa834d36ae0ee49c664736f6c634300080e0033",
"devdoc": {
"kind": "dev",
"methods": {},
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
},
"storageLayout": {
"storage": [],
"types": null
}
}