-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLocker.sol
89 lines (80 loc) · 2.87 KB
/
Locker.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
// import "hardhat/console.sol";
import "./Escrow.sol";
contract Locker is ReentrancyGuard {
enum LockState {
Locked,
Released,
Withdrawn
}
struct Lock {
address escrow;
address beneficiary;
address token;
uint256 amount;
uint256 mId;
uint256 unlockTimestamp;
LockState state;
}
/******************************* variables *******************************/
Lock[] private locks;
/******************************* modifiers *******************************/
modifier onlyLock(uint256 lockId) {
require(lockId < locks.length, "Locker: invalid lock index");
require(msg.sender == locks[lockId].escrow, "Locker: only escrow can call this function");
require(locks[lockId].state == LockState.Locked, "Locker: it is not locked");
_;
}
/******************************* functions *******************************/
/**
* @notice Create lock
* @param beneficiary: beneficiary address
* @param token: token address
* @param amount: token amount
* @param unlockTimestamp: unlock timestamp
* @param mId: milestone index
* @return lockId
*/
function create(
address beneficiary,
address token,
uint256 amount,
uint256 unlockTimestamp,
uint256 mId
) external nonReentrant returns (uint256) {
require(beneficiary != address(0), "Locker: beneficiary is not defined");
require(token != address(0), "Locker: token is not defined");
locks.push(Lock(msg.sender, beneficiary, token, amount, mId, unlockTimestamp, LockState.Locked));
return locks.length - 1;
}
/**
* @notice Release lock
* @param lockId: lock index
*/
function release(uint256 lockId) external onlyLock(lockId) nonReentrant {
Lock storage lock = locks[lockId];
require(
block.timestamp >= lock.unlockTimestamp + Escrow(lock.escrow).getLockDuration(),
"Locker: it is locked for now"
);
lock.state = LockState.Released;
IERC20(lock.token).transfer(lock.beneficiary, lock.amount);
}
/**
* @notice Originator withdraw fund
* @param lockId: lock Index
*/
function withdraw(uint256 lockId) external onlyLock(lockId) nonReentrant {
Lock storage lock = locks[lockId];
require(
block.timestamp < lock.unlockTimestamp + Escrow(lock.escrow).getLockDuration(),
"Locker: lock duration has already passed"
);
address originator = Escrow(lock.escrow).getOriginator();
lock.state = LockState.Withdrawn;
IERC20(lock.token).transfer(originator, lock.amount);
}
}