OsiPad/evm/contracts/PADTokenStake.sol

99 lines
2.2 KiB
Solidity

// 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);
}
}