// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import "./PADToken.sol"; contract PADTokenStake { // pool id => pool info mapping (uint => Pool) pools; // staker => deposits mapping(address => Deposit[]) deposits; uint nextPoolId = 0; uint nextDepositId = 0; PADToken immutable padToken; struct Pool { uint id; uint lockdownDays; uint rewardPercentage; } struct Deposit { uint id; address staker; uint poolId; uint amount; uint lockedAt; uint releasedAt; } constructor(PADToken _padToken) { padToken = _padToken; _initPools(); } function _initPools() internal { pools[0] = Pool({ id: nextPoolId, lockdownDays: 30, rewardPercentage: 25 }); nextPoolId++; pools[1] = Pool({ id: nextPoolId, lockdownDays: 60, rewardPercentage: 50 }); nextPoolId++; } function stake(uint poolId, uint amount) external { Pool memory pool = pools[poolId]; Deposit memory newDeposit = Deposit({ id: nextDepositId, staker: msg.sender, poolId: poolId, amount: amount, lockedAt: block.timestamp, releasedAt: block.timestamp + (pool.lockdownDays * 1 days) }); deposits[msg.sender].push(newDeposit); } function getDeposit(uint depositId) public view returns (Deposit memory) { Deposit memory deposit; for (uint i = 0; i < deposits[msg.sender].length; i++) { deposit = deposits[msg.sender][i]; if (deposit.id == depositId) { return deposit; } } revert("Deposit with the given ID not found."); } function getWithdrawPenalty(uint depositId) public view returns (uint) { Deposit memory deposit = getDeposit(depositId); uint remainingMs = deposit.releasedAt - block.timestamp; if (remainingMs <= 0) { return 0; } // TODO Find a meaningful formula return 100; } function withdraw(uint depositId, bool acceptPenaltyCut) external { uint penalty = getWithdrawPenalty(depositId); if (penalty > 0) { require(acceptPenaltyCut, "You should accept the penalty cut."); } Deposit memory deposit = getDeposit(depositId); Pool memory pool = pools[deposit.poolId]; uint amountToTransfer = (deposit.amount * pool.rewardPercentage / 100) - penalty; padToken.transfer(deposit.staker, amountToTransfer); } }