以下是一个的编程代码示例,用Solidity语言编写。
struct PoolInfo {
IERC20 lpToken;
INFT nftToken;
uint256 nftId;
uint256 nftRate;
uint256 lastRewardBlock;
uint256 accRewardPerShare;
}
PoolInfo[] public poolInfo;
mapping (uint256 => mapping (address => UserInfo)) public userInfo;
IERC20 public rewardToken;
uint256 public rewardPerBlock;
constructor(
IERC20 _rewardToken,
uint256 _rewardPerBlock
) public {
rewardToken = _rewardToken;
rewardPerBlock = _rewardPerBlock;
}
function addPool(
IERC20 _lpToken,
INFT _nftToken,
uint256 _nftId,
uint256 _nftRate,
bool _withUpdate
) public {
if (_withUpdate) {
massUpdatePools();
}
poolInfo.push(PoolInfo({
lpToken: _lpToken,
nftToken: _nftToken,
nftId: _nftId,
nftRate: _nftRate,
lastRewardBlock: block.number,
accRewardPerShare: 0
}));
}
function updatePool(uint256 _pid) public {
PoolInfo storage pool = poolInfo[_pid];
if (block.number <= pool.lastRewardBlock) {
return;
}
uint256 lpSupply = pool.lpToken.balanceOf(address(this));
if (lpSupply == 0) {
pool.lastRewardBlock = block.number;
return;
}
uint256 blocks = block.number - pool.lastRewardBlock;
uint256 reward = blocks * rewardPerBlock;
pool.accRewardPerShare += reward * 1e12 / lpSupply;
pool.lastRewardBlock = block.number;
}
function massUpdatePools() public {
uint256 length = poolInfo.length;
for (uint256 pid = 0; pid < length; ++pid) {
updatePool(pid);
}
}
function deposit(uint256 _pid, uint256 _amount) public {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
updatePool(_pid);
if (user.amount > 0) {
uint256 pending = user.amount * pool.accRewardPerShare / 1e12 - user.rewardDebt;
rewardToken.transfer(msg.sender, pending);
}
if (_amount > 0) {
pool.lpToken.transferFrom(msg.sender, address(this), _amount);
user.amount += _amount;
pool.nftToken.transferFrom(msg.sender, address(this), pool.nftId);