delegated vesting refactor

This commit is contained in:
gozzy 2023-03-11 21:08:48 +00:00
parent de6762b45c
commit eb35892b1c

View File

@ -1,5 +1,3 @@
// SPDX-License-Identifier: Unlicense
pragma solidity 0.8.0; pragma solidity 0.8.0;
import "./interfaces/IERC20.sol"; import "./interfaces/IERC20.sol";
@ -7,12 +5,12 @@ import "./interfaces/IGovernance.sol";
contract DelegatedInstance { contract DelegatedInstance {
address public spender; address public _spender;
address public sender; address public _sender;
uint256 public balance; uint256 public _balance;
IGovernance governance; address public _governanceAddress;
IERC20 token; address public _tokenAddress;
constructor( constructor(
address stakeholderAddress, address stakeholderAddress,
@ -20,139 +18,128 @@ contract DelegatedInstance {
address tokenAddress, address tokenAddress,
uint256 stakeAmount uint256 stakeAmount
) { ) {
governance = IGovernance(governanceAddress); _governanceAddress = governanceAddress;
token = IERC20(tokenAddress); _tokenAddress = tokenAddress;
spender = stakeholderAddress; _spender = stakeholderAddress;
balance = stakeAmount; _balance = stakeAmount;
sender = msg.sender; _sender = msg.sender;
} }
function delegate(address to) public { modifier isSpender() {
require(msg.sender == spender, "Incorrect spender"); require(msg.sender == _spender, "INVALID SPENDER");
_;
}
governance.delegate(to); function delegate(address to) public isSpender {
IGovernance(_governanceAddress).delegate(to);
} }
function lockAndDelegate( function lockAndDelegate(
address to, address to,
uint256 amount, uint256 deadline, uint256 amount,
uint8 v, bytes32 r, bytes32 s uint256 deadline,
) external { uint8 v,
require(msg.sender == sender); bytes32 r,
bytes32 s
token.transferFrom(msg.sender, address(this), amount); ) external isSpender {
governance.lock( IERC20(_tokenAddress).transferFrom(msg.sender, address(this), amount);
address(this), amount, deadline, v, r, s IGovernance(_governanceAddress).lock(address(this), amount, deadline, v, r, s);
); IGovernance(_governanceAddress).delegate(to);
governance.delegate(to);
} }
function unlockAndRedeem() public { function unlockAndRedeem() public isSpender {
require(msg.sender == sender, "Incorrect sender"); uint256 stake = _balance;
uint256 stake = balance;
delete balance; delete balance;
governance.unlock(stake);
token.transfer(spender, stake); IGovernance(_governanceAddress).unlock(stake);
IERC20(_tokenAddress).transfer(_spender, stake);
} }
} }
contract DelegatedVesting { contract DelegatedVesting {
uint256 public vestingPeriod; uint256 public _period;
address public vestingGovernance; address public _governanceAddress;
IERC20 public vestingToken; address public _tokenAddress;
mapping(address => uint256) balances; mapping(address => uint256) _balances;
mapping(address => address) delegations; mapping(address => address) _instance;
mapping(address => uint256) commitments; mapping(address => uint256) _commitments;
constructor( constructor(
uint256 vestingTimestamp, uint256 vestingDuration,
address governanceAddress, address governanceAddress,
address tokenAddress address tokenAddress
) { ) {
vestingPeriod = vestingTimestamp; _period = vestingDuration;
vestingToken = IERC20(tokenAddress); _tokenAddress = tokenAddress;
vestingGovernance = governanceAddress; _operatorAddress = msg.sender;
_governanceAddress = governanceAddress;
} }
function isActiveCommitment(address stakeholderAddress) public view returns (bool) { function isActiveCommitment(address stakeholder) public view returns (bool) {
uint256 commitment = commitments[stakeholderAddress]; return _balances[stakeholder] > 0 && _commitments[stakeholder] > block.timestamp;
uint256 stake = balances[stakeholderAddress];
return stake > 0 && commitment > now;
} }
function isDelegatedCommitment(address stakeholderAddress) public view returns (bool) { function isDelegatedCommitment(address stakeholder) public view returns (bool) {
uint256 delegated = delegations[stakeholderAddress]; return isActiveCommitment(stakeholder) && _instance[stakeholder] != address(0x0);
bool state = isActiveCommitment(stakeholderAddress);
return state && delegated != address(0x0);
} }
function isFulfilledCommitment(address stakeholderAddress) public view returns (bool) { function isFulfilledCommitment(address stakeholder) public view returns (bool) {
uint256 commitment = commitments[stakeholderAddress]; return _balances[stakeholder] > 0 && _commitments[stakeholder] < block.timestamp;
uint256 stake = balances[stakeholderAddress];
return stake > 0 && commitment < now;
} }
function makeCommitment( function makeCommitment(address stakeholder, uint256 amount) public {
address recipientAddress, require(IERC20(_tokenAddress).transferFrom(msg.sender, address(this), amount));
uint256 amount
) public {
require(vestingToken.transferFrom(msg.sender, address(this), amount));
commitments[recipientAddress] = vestingPeriod; _commitments[stakeholder] = block.timestmap + _period;
_balances[stakeholder] += amount;
if(isActiveCommitment(recipientAddress)) {
balances[recipientAddress] = balances[recipientAddress] + amount;
} else {
balances[recipientAddress] = amount;
}
} }
function delegateCommitment( function delegateCommitment(
address to, address delegateAddress,
uint256 deadline, uint256 deadline,
uint8 v, bytes32 r, bytes32 s uint8 v,
bytes32 r,
bytes32 s
) public { ) public {
require(isActiveCommitment(msg.sender), "Not an active commitment"); require(isActiveCommitment(msg.sender), "INVALID COMMITMENT");
if(isDelegatedCommitment(msg.sender)) { if(isDelegatedCommitment(msg.sender)) {
DelegatedInstance(delegations[msg.sender]).delegate(to); DelegatedInstance(_instance[msg.sender]).delegate(delegateAddress);
} else { } else {
DelegatedInstance e = new DelegatedInstance( DelegatedInstance e = new DelegatedInstance(
msg.sender, msg.sender,
vestingGovernance, _governanceAddress,
address(vestingToken), _tokenAddress,
balances[msg.sender], _balances[msg.sender],
deadline, deadline,
v, r, s v, r, s
); );
vestingToken.approve(address(e), balances[msg.sender]);
e.lockAndDelegate(to, balances[msg.sender], deadline, v, r, s); _instance[msg.sender] = address(e);
delegations[msg.sender] = address(e);
IERC20(_tokenAddress).approve(address(e), _balances[msg.sender]);
e.lockAndDelegate(delegateAddress, _balances[msg.sender], deadline, v, r, s);
} }
} }
function fulfilCommitment() public { function fulfillCommitment() public {
require(isFulfilledCommitment(msg.sender), "Commitment is not possible to fulfil"); require(isFulfilledCommitment(msg.sender), "INVALID FULFILLMENT");
uint256 stake = balances[msg.sender]; uint256 stake = _balances[msg.sender];
uint256 delegated = delegations[msg.sender]; address delegated = _instance[msg.sender];
delete balances[msg.sender]; delete _balances[msg.sender];
delete _instance[msg.sender];
if(delegated != address(0x0)){ if(delegated != address(0x0)){
delete delegations[msg.sender];
DelegatedInstance(delegated).unlockAndRedeem(); DelegatedInstance(delegated).unlockAndRedeem();
} else { } else {
vestingToken.transfer(msg.sender, stake); IERC20(_tokenAddress).transfer(msg.sender, stake);
} }
} }