Skip to content

Commit

Permalink
Add lock state for user stake in dividend contract
Browse files Browse the repository at this point in the history
  • Loading branch information
lurenpluto committed Jul 31, 2024
1 parent 7ef6eff commit f7bb2ba
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 4 deletions.
48 changes: 45 additions & 3 deletions contracts/dividend.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ contract DividendContract is Initializable, UUPSUpgradeable, ReentrancyGuardUpgr
mapping(address => bool) private tokenWhiteList;
address[] private tokenWhiteListArray;

// Lock state for users
mapping (address => uint256) lockState;
uint256 public lockBlocks;
address public proposalContract;

event TokenAddedToWhitelist(address token);
event TokenRemovedFromWhitelist(address token);
Expand All @@ -73,17 +77,20 @@ contract DividendContract is Initializable, UUPSUpgradeable, ReentrancyGuardUpgr
event NewCycle(uint256 cycleIndex, uint256 startBlock);
event Withdraw(address indexed user, address token, uint256 amount);

function initialize(address _stakingToken, uint256 _cycleMaxLength, address[] memory _tokenList) public initializer {
function initialize(address _stakingToken, uint256 _cycleMaxLength, address[] memory _tokenList, uint256 _lockBlocks, address _proposalContract) public initializer {
__UUPSUpgradeable_init();
__ReentrancyGuard_init();
__Ownable_init(msg.sender);
__DividendContractUpgradable_init(_stakingToken, _cycleMaxLength, _tokenList);
__DividendContractUpgradable_init(_stakingToken, _cycleMaxLength, _tokenList, _lockBlocks, _proposalContract);
}

function __DividendContractUpgradable_init(address _stakingToken, uint256 _cycleMaxLength, address[] memory _tokenList) public onlyInitializing {
function __DividendContractUpgradable_init(address _stakingToken, uint256 _cycleMaxLength, address[] memory _tokenList, uint256 _lockBlocks, address _proposalContract) public onlyInitializing {
stakingToken = _stakingToken;
cycleMaxLength = _cycleMaxLength;

lockBlocks = _lockBlocks;
proposalContract = _proposalContract;

for (uint i = 0; i < _tokenList.length; i++) {
tokenWhiteList[_tokenList[i]] = true;
tokenWhiteListArray.push(_tokenList[i]);
Expand Down Expand Up @@ -208,6 +215,36 @@ contract DividendContract is Initializable, UUPSUpgradeable, ReentrancyGuardUpgr
return tokenBalances[token];
}

function _updateLockState(address user) internal {
lockState[user] = block.number;
}

/**
* Update the lock state of the user, only the proposal contract can call this function, and return the current stake amount of the user
* @param user the user address to check
* @return the current stake amount of the user in total
*/
function updateLockState(address user) external returns (uint256) {
require(msg.sender == proposalContract, "Only proposal contract can call this function");

uint256 stakeAmount = _getStakeAmount(user, currentCycleIndex);

if (stakeAmount > 0) {
_updateLockState(user);
}

return stakeAmount;
}

/**
* Get the lock state of the user, use can not unstake if the lock state is true
* @param user the user address to check
* @return true if the user unstake is locked, otherwise false
*/
function isUserUnstakeLocked(address user) public view returns (bool) {
return block.number - lockState[user] <= lockBlocks;
}

// Deposit token as rewards to the current cycle
function _depositToken(address token, uint256 amount) internal {
require(amount > 0, "Cannot deposit 0");
Expand Down Expand Up @@ -328,6 +365,7 @@ contract DividendContract is Initializable, UUPSUpgradeable, ReentrancyGuardUpgr

// console.log("user stake ===> amount %d, cycle %d, user %s", amount, currentCycleIndex, msg.sender);

// The last stake record of the user is always the newest stake amount of the user in the contract
StakeRecord[] storage stakeRecords = UserStakeRecords[msg.sender];
if (stakeRecords.length == 0) {
stakeRecords.push(StakeRecord(currentCycleIndex, amount));
Expand All @@ -343,6 +381,9 @@ contract DividendContract is Initializable, UUPSUpgradeable, ReentrancyGuardUpgr
// Update the total staked amount of the contract
totalStaked += amount;

// Update the lock state of the user
_updateLockState(msg.sender);

// Emit the stake event
emit Stake(msg.sender, amount);
}
Expand All @@ -358,6 +399,7 @@ contract DividendContract is Initializable, UUPSUpgradeable, ReentrancyGuardUpgr
require(amount > 0, "Cannot unstake 0");
StakeRecord[] storage stakeRecords = UserStakeRecords[msg.sender];
require(stakeRecords.length > 0, "No stake record found");
require(!isUserUnstakeLocked(msg.sender), "Unstake is locked");

// console.log("user unstake <=== amount %d, cycle %d, user %s", amount, currentCycleIndex, msg.sender);

Expand Down
4 changes: 3 additions & 1 deletion test/test_dividend2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ describe("Devidend", function () {
"0x0000000000000000000000000000000000000000",
];

const proposalContract = "0x0000000000000000000000000000000000000000";

dividend = (await (
await upgrades.deployProxy(
await ethers.getContractFactory("DividendContract"),
[await dmc.getAddress(), 1000, tokenWhiteList]
[await dmc.getAddress(), 1000, tokenWhiteList, 500, proposalContract]
)
).waitForDeployment()) as unknown as DividendContract;

Expand Down

0 comments on commit f7bb2ba

Please sign in to comment.