diff --git a/ABI.json b/ABI.json index cea65a9..e95837e 100644 --- a/ABI.json +++ b/ABI.json @@ -1,315 +1,277 @@ [ - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "addr", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "string", - "name": "txid", - "type": "string" - } - ], - "name": "USDTLog", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "bool", - "name": "flag", - "type": "bool" - } - ], - "name": "changeStatus", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - }, - { - "internalType": "uint64", - "name": "timeSlice", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "count", - "type": "uint64" - }, - { - "internalType": "string", - "name": "txid", - "type": "string" - } - ], - "name": "lockLinear", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "name": "transferLock", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "paramOwner", - "type": "address" - } - ], - "name": "transferOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "withdrawAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "withdrawAmount", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "getAllCount", - "outputs": [ - { - "internalType": "uint256", - "name": "count", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "isEnabled", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "start", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "size", - "type": "uint256" - } - ], - "name": "queryAll", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - }, - { - "internalType": "uint256", - "name": "lockedAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "withdrawed", - "type": "uint256" - }, - { - "internalType": "uint64", - "name": "startTime", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "slice", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "count", - "type": "uint64" - } - ], - "internalType": "struct Lock.QueryResult[]", - "name": "", - "type": "tuple[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "name": "queryAny", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - }, - { - "internalType": "uint256", - "name": "lockedAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "withdrawed", - "type": "uint256" - }, - { - "internalType": "uint64", - "name": "startTime", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "slice", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "count", - "type": "uint64" - } - ], - "internalType": "struct Lock.QueryResult", - "name": "result", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "querySelf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - }, - { - "internalType": "uint256", - "name": "lockedAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "withdrawed", - "type": "uint256" - }, - { - "internalType": "uint64", - "name": "startTime", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "slice", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "count", - "type": "uint64" - } - ], - "internalType": "struct Lock.QueryResult", - "name": "result", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - } -] \ No newline at end of file + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "txid", + "type": "string" + } + ], + "name": "USDTLog", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "QueryAny", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "lockedAmount", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "startTime", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "withdrawed", + "type": "uint256" + } + ], + "internalType": "struct Lock.QueryResult", + "name": "result", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "flag", + "type": "bool" + } + ], + "name": "changeStatus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAllCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isEnable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "txidUSDT", + "type": "string" + } + ], + "name": "lock_540_once", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "size", + "type": "uint256" + } + ], + "name": "queryAll", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "lockedAmount", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "startTime", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "withdrawed", + "type": "uint256" + } + ], + "internalType": "struct Lock.QueryResult[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "querySelf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "lockedAmount", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "startTime", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "withdrawed", + "type": "uint256" + } + ], + "internalType": "struct Lock.QueryResult", + "name": "result", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "transferLock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "paramOwner", + "type": "address" + } + ], + "name": "transferOnwer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdraAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/Lock.sol b/Lock.sol index 443f7ea..97da43e 100644 --- a/Lock.sol +++ b/Lock.sol @@ -1,215 +1,151 @@ +// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; contract Lock { - //合约拥有者账号地址 address private owner; - mapping(address => Record) records; - mapping(address => uint) balances; + mapping (address => Record) records; address[] users; - + bool _enabled = true; - + //抵押状态 struct Record { - //抵押额度(wei) + //抵押额度 wei uint value; - //单次提取时间(s) - uint64 slice; - //抵押起始时间(s) + //抵押起始时间 uint64 startTime; //总提取次数 - uint64 count; - //已提取次数 - uint64 freeCount; - //用户索引 uint index; } - + struct QueryResult { address addr; uint lockedAmount; - uint withdrawed; uint64 startTime; - uint64 slice; - uint64 count; + uint withdrawed; } - + constructor() { owner = msg.sender; } - - event USDTLog(address addr, uint amount, string txid); - - //直接抵押函数 - function lockLinear(address addr, uint64 timeSlice, uint64 count, string calldata txid) public payable { - require(msg.value > 0, "value cannot be zero"); - require(address(msg.sender) == address(tx.origin), "no contract"); - require(_enabled, "is disabled"); - require(count > 0 && count <= 36, "illegal count"); - require(timeSlice > 0 && timeSlice < 36500, "illegal time"); - require(records[addr].value == 0, "lock exist"); - + + event USDTLog(address indexed addr, uint amount, string txid); + + + function lock_540_once(address addr, uint amount, string calldata txidUSDT) public payable { + require(msg.value > 0,"value cannot be zero"); + require(address(msg.sender) == address(tx.origin),"no cantract"); + require(_enabled,"is disable"); + require(records[addr].value == 0,"lock exist"); + require(msg.value >= amount,"amount false"); + records[addr] = Record({ - value : msg.value, - slice : timeSlice * (1 days), - startTime : uint64(block.timestamp), - count : count, - freeCount : 0, - index : users.length + value : msg.value, + startTime : uint64(block.timestamp), + index : users.length }); - users.push(addr); - emit USDTLog(addr, msg.value, txid); + emit USDTLog(addr, msg.value, txidUSDT); } - - //查询自身锁仓 - function querySelf() view public returns (uint, QueryResult memory result) { - require(records[msg.sender].value > 0, "no record"); + + function querySelf() view public returns(uint, QueryResult memory result) { + require(records[msg.sender].value > 0,"no records"); Record storage curRecord = records[msg.sender]; - uint share = curRecord.value / curRecord.count; - - result = QueryResult({ - addr : msg.sender, - lockedAmount : curRecord.value, - withdrawed : share * curRecord.freeCount, - startTime : curRecord.startTime, - slice : curRecord.slice, - count : curRecord.count - }); - return (block.timestamp, result); - } - - //查询指定锁仓 - function queryAny(address addr) view public onlyOwner returns (QueryResult memory result) { - require(records[addr].value > 0, "no record"); - Record storage curRecord = records[addr]; - uint share = curRecord.value / curRecord.count; - + result = QueryResult({ - addr : addr, - lockedAmount : curRecord.value, - withdrawed : share * curRecord.freeCount, - startTime : curRecord.startTime, - slice : curRecord.slice, - count : curRecord.count + addr : msg.sender, + lockedAmount : curRecord.value, + withdrawed : 0, + startTime : curRecord.startTime }); - return result; - } - - //查询全部锁仓 - function queryAll(uint start, uint size) view public onlyOwner returns (QueryResult[] memory) { - require(start + size <= users.length, "overflow"); + return(block.timestamp, result); + } + + function queryAll(uint start, uint size) view public onlyOwner returns(uint, QueryResult[] memory) { + require(start + size <= users.length,"overflow"); QueryResult[] memory result = new QueryResult[](size); - - uint end = start + size; - for (uint i = start; i < end; i++) { + uint end =start + size; + for (uint i = start; i < end; i++){ Record storage curRecord = records[users[i]]; - uint share = curRecord.value / curRecord.count; - result[i - start] = QueryResult({ - addr : users[i], - lockedAmount : curRecord.value, - withdrawed : share * curRecord.freeCount, - startTime : curRecord.startTime, - slice : curRecord.slice, - count : curRecord.count + result[i-start] = QueryResult({ + addr : users[i], + lockedAmount : curRecord.value, + withdrawed : 0, + startTime : curRecord.startTime }); } - return result; + return (block.timestamp,result); } - - function getAllCount() onlyOwner public view returns (uint count) { - return users.length; + + function QueryAny(address addr) view public onlyOwner returns(uint, QueryResult memory result){ + require(records[addr].value > 0, "no record"); + Record storage curRecord = records[addr]; + result = QueryResult({ + addr : addr, + lockedAmount : curRecord.value, + withdrawed : 0, + startTime : curRecord.startTime + }); + return (block.timestamp, result); } - + function deleteUser(address addr) private { - //删除用户 uint index = records[addr].index; uint end = users.length - 1; if (index < end) { users[index] = users[end]; - records[users[end]].index = index; + records[users[end]].index = index; } users.pop(); delete records[addr]; } - - function settle_(address addr) private { - Record storage curRecord = records[addr]; - uint share = curRecord.value / curRecord.count; + + + function withdraAll() public { + require(address(msg.sender) == address(tx.origin),"no cantract"); + Record storage curRecord = records[msg.sender]; uint curTime = block.timestamp; - - //抵押已到期 - if (curTime >= curRecord.startTime + curRecord.slice * curRecord.count) { - //剩余抵押 - uint amount = curRecord.value - share * curRecord.freeCount; - curRecord.freeCount = curRecord.count; - balances[addr] += amount; - deleteUser(addr); - return; - } - - uint times = (curTime - uint(curRecord.startTime)) / curRecord.slice; - //按时间释放 - if (times > curRecord.freeCount) { - uint amount = (times - curRecord.freeCount) * share; - curRecord.freeCount = uint64(times); - balances[addr] += amount; - } - } - - //提取指定余额 - function withdrawAmount(uint amount) public { - require(address(msg.sender) == address(tx.origin), "no contract"); - if (records[msg.sender].value > 0) { - settle_(msg.sender); - } - - require(balances[msg.sender] >= amount, "not enough"); - balances[msg.sender] -= amount; - payable(msg.sender).transfer(amount); - } - - //提取全部余额 - function withdrawAll() public { - require(address(msg.sender) == address(tx.origin), "no contract"); - if (records[msg.sender].value > 0) { - settle_(msg.sender); - } - - uint amount = balances[msg.sender]; - balances[msg.sender] = 0; - payable(msg.sender).transfer(amount); + uint64 day = uint64(((curTime) / (1 days)) - ((curRecord.startTime) / (1 days))); + if (day > 540){ + deleteUser(msg.sender); + payable(msg.sender).transfer(curRecord.value); + } + } + + + function getAllCount() view public onlyOwner returns(uint) { + return users.length; } - + function transferLock(address addr) public { - require(records[addr].value == 0, "lock exist"); - require(addr != msg.sender, "no self"); - + require(records[addr].value ==0, "lock exist"); + require(addr != msg.sender && addr != address(0), "not self"); + users.push(addr); records[addr] = records[msg.sender]; deleteUser(msg.sender); } - - //设置开始状态 - function changeStatus(bool flag) public onlyOwner { - _enabled = flag; + + function transferOnwer(address paramOwner) public onlyOwner { + if (paramOwner != address(0)){ + owner = paramOwner; + } } - - function transferOwner(address paramOwner) public onlyOwner { - require(paramOwner != address(0)); - owner = paramOwner; + + function changeStatus(bool flag) public onlyOwner { + _enabled = flag; } - - modifier onlyOwner(){ - require(msg.sender == owner, "only owner"); + + modifier onlyOwner() { + require (msg.sender == owner,"only owner"); _; } - + function getOwner() public view returns (address) { return owner; } - - function isEnabled() public view returns (bool) { + + function isEnable() public view returns (bool) { return _enabled; } -} \ No newline at end of file +} diff --git a/Readme.md b/Readme.md index 0c89ec3..f03f6c5 100644 --- a/Readme.md +++ b/Readme.md @@ -1,3 +1,49 @@ ## ETD Lock Contract -address: 0x3d90df95377811A4E0574Dfe9069fD319FE5eB2D \ No newline at end of file +address: 0x7b7c74c2d0f4b7222ede26cae13a4e85a3b69e90 + +1. Lock_540_once(addr, amount, usdtTxid) + + 1.addr 为锁仓收款地址 + 2.amount为锁定数量 + 3.txidUSDT可以为空 + 4.每⼀个addr持有的锁仓条⽬上限为1 + 5. 释放规则(分为两个线性阶段): + 1. 从锁仓开始记为第⼀天,第540天⼀次性释放 + +2. withdrawAll() + + 提取msg.sender的当前可以提取的所有ETD(⼀次性释放,即为>=540天后,可提取全部,<540时可提取为0) + + +3. querySelf()// {now, addr, lockedAmount, withdrawed, startTime} + + 查询msg.sender的锁仓列表 + +4. queryAll _owner(start, size)// {now, []{addr, lockedAmount, withdrawed, startTime}} + + 查询所有的锁仓详情,owner权限 + +6. queryAny _owner(addr) // {now, addr, lockedAmount, withdrawed, startTime} + + 查询addr的锁仓详情,owner权限 + +7. getAllCount _owner() + + 当前锁仓总条数 + +8. transferLock(addr) + + 转移msg.sender的锁仓记录给addr + +9. transferOwner _owner(addr) + + 转移owner权限 + +10. getOwer() + + 返回owner地址 + +11. changeStatus _owner() + + 开启/关闭锁仓功能