- Contract name:
- FixedLock
- Optimization enabled
- true
- Compiler version
- v0.8.19+commit.7dd6d404
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2024-05-09T07:28:25.697504Z
Contract source code
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0 ; library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { assembly { r.slot := slot } } function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { assembly { r.slot := slot } } function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { assembly { r.slot := slot } } function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { assembly { r.slot := slot } } } abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } function _disableInitializers() internal { _initialized = true; } } contract FixedLock is Initializable { uint256 public startTime; uint256 public endTime; uint256 public releaseStart; //2026-04-16 00:00:00 uint256 public releaseEnd; //2030-04-16 00:00:00 uint256 public releaseDuration; uint256 public totalLocked; uint256 public rewardPropotion; uint256 public rewardDelay; struct LockInfo{ address owner; uint256 locked; uint256 lockTime; uint256 unlocked; uint256 rewardsEarned; } uint256 public lockId; mapping(uint256 => LockInfo) public lockInfo; //lockId => lockInfo mapping(address => uint256[]) private locks; //owner => lockId[] //new tokenomic bool public isReset; event Lock(uint256 indexed id, address indexed owner, uint256 amt); event Unlock(uint256 indexed id, address indexed owner, uint256 amt); event ClaimReward(uint256 indexed id, address indexed owner, uint256 amt); modifier notContract() { require((!_isContract(msg.sender)) && (msg.sender == tx.origin), "contract not allowed"); _; } modifier onlyOwner() { require(msg.sender == owner(), "only owner allowed"); _; } function _isContract(address addr) internal view returns (bool) { uint256 size; assembly { size := extcodesize(addr) } return size > 0; } constructor(){_disableInitializers();} function init(uint256 _endTime, uint256 _lockDuration, uint256 _rewardPropotion, uint256 _rewardDelay, bool _isMainNet) public initializer{ //already initialized /* require(endTime > block.timestamp,"invalid time"); startTime = block.timestamp; endTime = _endTime; releaseTimes = 8; releasePeriod = _isMainNet? 365 days: 1 minutes; deadLockDuration = _lockDuration; rewardPropotion = _rewardPropotion; rewardDelay = _rewardDelay; */ } function owner() public view returns(address){ //EIP1967 Admin_solt: keccak-256 hash of "eip1967.proxy.admin" subtracted by 1 bytes32 _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; } function getLocks(address guy) public view returns(uint256[] memory){ return locks[guy]; } function getLockInfos(address guy) public view returns(LockInfo[] memory){ uint256[] memory lockIds = locks[guy]; LockInfo[] memory ls = new LockInfo[](lockIds.length); for(uint256 i=0; i<lockIds.length; i++){ ls[i] = lockInfo[lockIds[i]]; } return ls; } function lock(uint256 amt) public payable notContract returns(uint256 id){ amt = amt * 1e18; require(block.timestamp > startTime, "activit not start"); require(block.timestamp < endTime, "activit end"); require(msg.value == amt , "invaild NMT value"); //save LockInfo totalLocked += amt; lockInfo[++lockId] = LockInfo(msg.sender, amt, block.timestamp, 0, 0); locks[msg.sender].push(lockId); emit Lock(lockId, msg.sender, amt); return lockId; } function released(uint256 id) public view returns (uint256){ LockInfo memory lf = lockInfo[id]; if (lf.locked == 0 || block.timestamp < releaseStart || lf.locked == lf.unlocked){ return 0; } uint256 released_t = block.timestamp <= releaseEnd? block.timestamp - releaseStart : releaseEnd - releaseStart; return (lf.locked * released_t / releaseDuration) - lf.unlocked; } function unlock(uint256 id, uint256 amt) public notContract{ amt = amt * 1e18; LockInfo storage lf = lockInfo[id]; require(lf.locked > 0, "lockId unexsit"); require(lf.owner == msg.sender, "only owner can call"); require(amt > 0, "amt can not be zero"); //unlockable uint256 _released = released(id); require(amt <= _released && _released <= lf.locked, "out of unlockable"); //release totalLocked -= amt; lf.unlocked += amt; payable(msg.sender).transfer(amt); emit Unlock(lockId, msg.sender, amt); } function checkReward(uint256 id) public view returns(uint256){ LockInfo memory lf = lockInfo[id]; if (block.timestamp < lf.lockTime + rewardDelay || lf.rewardsEarned > 0){ return 0; } return lf.locked * rewardPropotion / 1000; } function claimReward(uint256 id) public notContract{ LockInfo storage lf = lockInfo[id]; require(lf.locked > 0, "lockId unexsit"); require(lf.owner == msg.sender, "only owner can call"); require(lf.rewardsEarned == 0, "already claim"); require(block.timestamp > lf.lockTime + rewardDelay, "unarrived claim time"); //claim reward uint256 reward = lf.locked * rewardPropotion / 1000; require(address(this).balance - reward >= totalLocked, "reward used up"); lf.rewardsEarned = reward; payable(msg.sender).transfer(reward); emit ClaimReward(id, msg.sender, reward); } }
Contract ABI
[{"type":"constructor","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"checkReward","inputs":[{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimReward","inputs":[{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"endTime","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct FixedLock.LockInfo[]","components":[{"type":"address"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"}]}],"name":"getLockInfos","inputs":[{"type":"address","name":"guy","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getLocks","inputs":[{"type":"address","name":"guy","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"init","inputs":[{"type":"uint256","name":"_endTime","internalType":"uint256"},{"type":"uint256","name":"_lockDuration","internalType":"uint256"},{"type":"uint256","name":"_rewardPropotion","internalType":"uint256"},{"type":"uint256","name":"_rewardDelay","internalType":"uint256"},{"type":"bool","name":"_isMainNet","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isReset","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[{"type":"uint256","name":"id","internalType":"uint256"}],"name":"lock","inputs":[{"type":"uint256","name":"amt","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lockId","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"uint256","name":"locked","internalType":"uint256"},{"type":"uint256","name":"lockTime","internalType":"uint256"},{"type":"uint256","name":"unlocked","internalType":"uint256"},{"type":"uint256","name":"rewardsEarned","internalType":"uint256"}],"name":"lockInfo","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"releaseDuration","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"releaseEnd","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"releaseStart","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"released","inputs":[{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardDelay","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardPropotion","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"startTime","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalLocked","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unlock","inputs":[{"type":"uint256","name":"id","internalType":"uint256"},{"type":"uint256","name":"amt","internalType":"uint256"}]},{"type":"event","name":"ClaimReward","inputs":[{"type":"uint256","name":"id","indexed":true},{"type":"address","name":"owner","indexed":true},{"type":"uint256","name":"amt","indexed":false}],"anonymous":false},{"type":"event","name":"Lock","inputs":[{"type":"uint256","name":"id","indexed":true},{"type":"address","name":"owner","indexed":true},{"type":"uint256","name":"amt","indexed":false}],"anonymous":false},{"type":"event","name":"Unlock","inputs":[{"type":"uint256","name":"id","indexed":true},{"type":"address","name":"owner","indexed":true},{"type":"uint256","name":"amt","indexed":false}],"anonymous":false}]
Deployed ByteCode
0x60806040526004361061011f5760003560e01c806378e97925116100a0578063ae169a5011610064578063ae169a5014610384578063dd467064146103a4578063e4698991146103b7578063f6b4ba6f146103d7578063f9b41891146103ed57600080fd5b806378e97925146102c45780638033fe49146102da5780638af37ef1146102f05780638da5cb5b1461031d578063a94d373b1461036457600080fd5b80635bfadb24116100e75780635bfadb241461023557806366fa19321461025557806370fe1ad11461026b578063719f308914610281578063766e33f4146102ae57600080fd5b80631f8b8aac146101245780633197cbb614610146578063568914121461016f57806357b082fc146101855780635b1a4c24146101af575b600080fd5b34801561013057600080fd5b5061014461013f366004610ee7565b610403565b005b34801561015257600080fd5b5061015c60025481565b6040519081526020015b60405180910390f35b34801561017b57600080fd5b5061015c60065481565b34801561019157600080fd5b50600c5461019f9060ff1681565b6040519015158152602001610166565b3480156101bb57600080fd5b506102036101ca366004610f39565b600a60205260009081526040902080546001820154600283015460038401546004909401546001600160a01b0390931693919290919085565b604080516001600160a01b0390961686526020860194909452928401919091526060830152608082015260a001610166565b34801561024157600080fd5b50610144610250366004610f52565b6104c0565b34801561026157600080fd5b5061015c60095481565b34801561027757600080fd5b5061015c60085481565b34801561028d57600080fd5b506102a161029c366004610f74565b6106e5565b6040516101669190610f9d565b3480156102ba57600080fd5b5061015c60035481565b3480156102d057600080fd5b5061015c60015481565b3480156102e657600080fd5b5061015c60045481565b3480156102fc57600080fd5b5061031061030b366004610f74565b610751565b6040516101669190610fe1565b34801561032957600080fd5b507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103546040516001600160a01b039091168152602001610166565b34801561037057600080fd5b5061015c61037f366004610f39565b6108fb565b34801561039057600080fd5b5061014461039f366004610f39565b6109dd565b61015c6103b2366004610f39565b610c20565b3480156103c357600080fd5b5061015c6103d2366004610f39565b610e46565b3480156103e357600080fd5b5061015c60075481565b3480156103f957600080fd5b5061015c60055481565b600054610100900460ff168061041c575060005460ff16155b6104845760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b600054610100900460ff161580156104a6576000805461ffff19166101011790555b80156104b8576000805461ff00191690555b505050505050565b333b1580156104ce57503332145b6104ea5760405162461bcd60e51b815260040161047b90611058565b6104fc81670de0b6b3a764000061109c565b6000838152600a602052604090206001810154919250906105505760405162461bcd60e51b815260206004820152600e60248201526d1b1bd8dad259081d5b995e1cda5d60921b604482015260640161047b565b80546001600160a01b0316331461059f5760405162461bcd60e51b81526020600482015260136024820152721bdb9b1e481bdddb995c8818d85b8818d85b1b606a1b604482015260640161047b565b600082116105e55760405162461bcd60e51b8152602060048201526013602482015272616d742063616e206e6f74206265207a65726f60681b604482015260640161047b565b60006105f0846108fb565b9050808311158015610606575081600101548111155b6106465760405162461bcd60e51b81526020600482015260116024820152706f7574206f6620756e6c6f636b61626c6560781b604482015260640161047b565b826006600082825461065891906110b9565b925050819055508282600301600082825461067391906110cc565b9091555050604051339084156108fc029085906000818181858888f193505050501580156106a5573d6000803e3d6000fd5b506009546040518481523391907f4899036909435f0ef100b2258d67d9c644af96bf047bac9f60cbd65f59a80e749060200160405180910390a350505050565b6001600160a01b0381166000908152600b602090815260409182902080548351818402810184019094528084526060939283018282801561074557602002820191906000526020600020905b815481526020019060010190808311610731575b50505050509050919050565b6001600160a01b0381166000908152600b602090815260408083208054825181850281018501909352808352606094938301828280156107b057602002820191906000526020600020905b81548152602001906001019080831161079c575b505050505090506000815167ffffffffffffffff8111156107d3576107d36110df565b60405190808252806020026020018201604052801561083f57816020015b61082c6040518060a0016040528060006001600160a01b03168152602001600081526020016000815260200160008152602001600081525090565b8152602001906001900390816107f15790505b50905060005b82518110156108f357600a6000848381518110610864576108646110f5565b6020908102919091018101518252818101929092526040908101600020815160a08101835281546001600160a01b031681526001820154938101939093526002810154918301919091526003810154606083015260040154608082015282518390839081106108d5576108d56110f5565b602002602001018190525080806108eb9061110b565b915050610845565b509392505050565b6000818152600a60209081526040808320815160a08101835281546001600160a01b03168152600182015493810184905260028201549281019290925260038101546060830152600401546080820152901580610959575060035442105b8061096b575080606001518160200151145b156109795750600092915050565b600060045442111561099a5760035460045461099591906110b9565b6109a7565b6003546109a790426110b9565b905081606001516005548284602001516109c1919061109c565b6109cb9190611124565b6109d591906110b9565b949350505050565b333b1580156109eb57503332145b610a075760405162461bcd60e51b815260040161047b90611058565b6000818152600a602052604090206001810154610a575760405162461bcd60e51b815260206004820152600e60248201526d1b1bd8dad259081d5b995e1cda5d60921b604482015260640161047b565b80546001600160a01b03163314610aa65760405162461bcd60e51b81526020600482015260136024820152721bdb9b1e481bdddb995c8818d85b8818d85b1b606a1b604482015260640161047b565b600481015415610ae85760405162461bcd60e51b815260206004820152600d60248201526c616c726561647920636c61696d60981b604482015260640161047b565b6008548160020154610afa91906110cc565b4211610b3f5760405162461bcd60e51b8152602060048201526014602482015273756e6172726976656420636c61696d2074696d6560601b604482015260640161047b565b60006103e86007548360010154610b56919061109c565b610b609190611124565b600654909150610b7082476110b9565b1015610baf5760405162461bcd60e51b815260206004820152600e60248201526d072657761726420757365642075760941b604482015260640161047b565b60048201819055604051339082156108fc029083906000818181858888f19350505050158015610be3573d6000803e3d6000fd5b50604051818152339084907fa756e4d8f7509f4ea7c440cd474be2db34f2c8e4a142b5bfbee53cb92124c6df9060200160405180910390a3505050565b6000333b158015610c3057503332145b610c4c5760405162461bcd60e51b815260040161047b90611058565b610c5e82670de0b6b3a764000061109c565b91506001544211610ca55760405162461bcd60e51b81526020600482015260116024820152701858dd1a5d9a5d081b9bdd081cdd185c9d607a1b604482015260640161047b565b6002544210610ce45760405162461bcd60e51b815260206004820152600b60248201526a1858dd1a5d9a5d08195b9960aa1b604482015260640161047b565b813414610d275760405162461bcd60e51b8152602060048201526011602482015270696e7661696c64204e4d542076616c756560781b604482015260640161047b565b8160066000828254610d3991906110cc565b925050819055506040518060a00160405280336001600160a01b03168152602001838152602001428152602001600081526020016000815250600a6000600960008154610d859061110b565b9182905550815260208082019290925260409081016000908120845181546001600160a01b0319166001600160a01b03909116178155848401516001808301919091558584015160028301556060860151600383015560809095015160049091015533808252600b84528282206009805482549788018355918452928590209095019490945554905185815290917f8738fac4c3f6ded3649d1d6c64679bd1a81c89414e861f2ca28b5fc585c0e33d910160405180910390a3505060095490565b6000818152600a60209081526040808320815160a08101835281546001600160a01b03168152600182015493810193909352600281015491830182905260038101546060840152600401546080830152600854610ea2916110cc565b421080610eb3575060008160800151115b15610ec15750600092915050565b6103e86007548260200151610ed6919061109c565b610ee09190611124565b9392505050565b600080600080600060a08688031215610eff57600080fd5b8535945060208601359350604086013592506060860135915060808601358015158114610f2b57600080fd5b809150509295509295909350565b600060208284031215610f4b57600080fd5b5035919050565b60008060408385031215610f6557600080fd5b50508035926020909101359150565b600060208284031215610f8657600080fd5b81356001600160a01b0381168114610ee057600080fd5b6020808252825182820181905260009190848201906040850190845b81811015610fd557835183529284019291840191600101610fb9565b50909695505050505050565b602080825282518282018190526000919060409081850190868401855b8281101561104b57815180516001600160a01b0316855286810151878601528581015186860152606080820151908601526080908101519085015260a09093019290850190600101610ffe565b5091979650505050505050565b60208082526014908201527318dbdb9d1c9858dd081b9bdd08185b1b1bddd95960621b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176110b3576110b3611086565b92915050565b818103818111156110b3576110b3611086565b808201808211156110b3576110b3611086565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60006001820161111d5761111d611086565b5060010190565b60008261114157634e487b7160e01b600052601260045260246000fd5b50049056fea264697066735822122065b0694c5a2f15b1dbb29e00795da2714d584b3026ca9c4276ba8d617027652064736f6c63430008130033