Diff
checker
Texte
Texte
Images
Documents
Excel
Dossiers
Legal
Enterprise
Application de bureau
Prix
Se connecter
Télécharger Diffchecker Desktop
Comparer le texte
Trouver la différence entre deux fichiers texte
Outils
Historique
Éditeur live
Cacher identiques
Sans retour à la ligne
Vue
Divisé
Unifié
Niveau de précision
Intelligent
Mot
Caractère
Coloration syntaxique
Choisir la syntaxe
Ignorer
Transformer le texte
Aller au premier écart
Modifier l'entrée
Diffchecker Desktop
La façon la plus sécurisée d'utiliser Diffchecker. Obtenez l'application Diffchecker Desktop : vos diffs ne quittent jamais votre ordinateur !
Obtenir Desktop
BEP20RewardApe-to-BEP20RewardApeV2
Créé
il y a 5 ans
Le diff n'expire jamais
Effacer
Exporter
Partager
Expliquer
0 suppressions
Lignes
Total
Supprimé
Caractères
Total
Supprimé
Pour continuer à utiliser cette fonctionnalité, passez à
Diff
checker
Pro
Voir les prix
236 lignes
Copier tout
14 ajouts
Lignes
Total
Ajouté
Caractères
Total
Ajouté
Pour continuer à utiliser cette fonctionnalité, passez à
Diff
checker
Pro
Voir les prix
249 lignes
Copier tout
pragma solidity 0.6.12;
pragma solidity 0.6.12;
/*
/*
* ApeSwapFinance
* ApeSwapFinance
* App: https://apeswap.finance
* App: https://apeswap.finance
* Medium: https://ape-swap.medium.com
* Medium: https://ape-swap.medium.com
* Twitter: https://twitter.com/ape_swap
* Twitter: https://twitter.com/ape_swap
* Telegram: https://t.me/ape_swap
* Telegram: https://t.me/ape_swap
* Announcements: https://t.me/ape_swap_news
* Announcements: https://t.me/ape_swap_news
* GitHub: https://github.com/ApeSwapFinance
* GitHub: https://github.com/ApeSwapFinance
*/
*/
import '@pancakeswap/pancake-swap-lib/contracts/math/SafeMath.sol';
import '@pancakeswap/pancake-swap-lib/contracts/math/SafeMath.sol';
import '@pancakeswap/pancake-swap-lib/contracts/token/BEP20/IBEP20.sol';
import '@pancakeswap/pancake-swap-lib/contracts/token/BEP20/IBEP20.sol';
import '@pancakeswap/pancake-swap-lib/contracts/token/BEP20/SafeBEP20.sol';
import '@pancakeswap/pancake-swap-lib/contracts/token/BEP20/SafeBEP20.sol';
import '@pancakeswap/pancake-swap-lib/contracts/access/Ownable.sol';
import '@pancakeswap/pancake-swap-lib/contracts/access/Ownable.sol';
Copier
Copié
Copier
Copié
contract BEP20RewardApe
is Ownable {
contract BEP20RewardApe
V2
is Ownable {
using SafeMath for uint256;
using SafeMath for uint256;
using SafeBEP20 for IBEP20;
using SafeBEP20 for IBEP20;
// Info of each user.
// Info of each user.
struct UserInfo {
struct UserInfo {
uint256 amount; // How many LP tokens the user has provided.
uint256 amount; // How many LP tokens the user has provided.
uint256 rewardDebt; // Reward debt. See explanation below.
uint256 rewardDebt; // Reward debt. See explanation below.
}
}
// Info of each pool.
// Info of each pool.
struct PoolInfo {
struct PoolInfo {
IBEP20 lpToken; // Address of LP token contract.
IBEP20 lpToken; // Address of LP token contract.
uint256 allocPoint; // How many allocation points assigned to this pool. Rewards to distribute per block.
uint256 allocPoint; // How many allocation points assigned to this pool. Rewards to distribute per block.
uint256 lastRewardBlock; // Last block number that Rewards distribution occurs.
uint256 lastRewardBlock; // Last block number that Rewards distribution occurs.
uint256 accRewardTokenPerShare; // Accumulated Rewards per share, times 1e12. See below.
uint256 accRewardTokenPerShare; // Accumulated Rewards per share, times 1e12. See below.
}
}
// The stake token
// The stake token
IBEP20 public stakeToken;
IBEP20 public stakeToken;
// The reward token
// The reward token
IBEP20 public rewardToken;
IBEP20 public rewardToken;
// Reward tokens created per block.
// Reward tokens created per block.
uint256 public rewardPerBlock;
uint256 public rewardPerBlock;
// Info of each pool.
// Info of each pool.
PoolInfo[] public poolInfo;
PoolInfo[] public poolInfo;
// Info of each user that stakes LP tokens.
// Info of each user that stakes LP tokens.
mapping (address => UserInfo) public userInfo;
mapping (address => UserInfo) public userInfo;
// Total allocation poitns. Must be the sum of all allocation points in all pools.
// Total allocation poitns. Must be the sum of all allocation points in all pools.
uint256 private totalAllocPoint = 0;
uint256 private totalAllocPoint = 0;
// The block number when Reward mining starts.
// The block number when Reward mining starts.
uint256 public startBlock;
uint256 public startBlock;
// The block number when mining ends.
// The block number when mining ends.
uint256 public bonusEndBlock;
uint256 public bonusEndBlock;
event Deposit(address indexed user, uint256 amount);
event Deposit(address indexed user, uint256 amount);
event DepositRewards(uint256 amount);
event DepositRewards(uint256 amount);
event Withdraw(address indexed user, uint256 amount);
event Withdraw(address indexed user, uint256 amount);
event EmergencyWithdraw(address indexed user, uint256 amount);
event EmergencyWithdraw(address indexed user, uint256 amount);
event EmergencyRewardWithdraw(address indexed user, uint256 amount);
event EmergencyRewardWithdraw(address indexed user, uint256 amount);
constructor(
constructor(
IBEP20 _stakeToken,
IBEP20 _stakeToken,
IBEP20 _rewardToken,
IBEP20 _rewardToken,
uint256 _rewardPerBlock,
uint256 _rewardPerBlock,
uint256 _startBlock,
uint256 _startBlock,
uint256 _bonusEndBlock
uint256 _bonusEndBlock
) public {
) public {
stakeToken = _stakeToken;
stakeToken = _stakeToken;
rewardToken = _rewardToken;
rewardToken = _rewardToken;
rewardPerBlock = _rewardPerBlock;
rewardPerBlock = _rewardPerBlock;
startBlock = _startBlock;
startBlock = _startBlock;
bonusEndBlock = _bonusEndBlock;
bonusEndBlock = _bonusEndBlock;
// staking pool
// staking pool
poolInfo.push(PoolInfo({
poolInfo.push(PoolInfo({
lpToken: _stakeToken,
lpToken: _stakeToken,
allocPoint: 1000,
allocPoint: 1000,
lastRewardBlock: startBlock,
lastRewardBlock: startBlock,
accRewardTokenPerShare: 0
accRewardTokenPerShare: 0
}));
}));
totalAllocPoint = 1000;
totalAllocPoint = 1000;
}
}
// Return reward multiplier over the given _from to _to block.
// Return reward multiplier over the given _from to _to block.
function getMultiplier(uint256 _from, uint256 _to) public view returns (uint256) {
function getMultiplier(uint256 _from, uint256 _to) public view returns (uint256) {
if (_to <= bonusEndBlock) {
if (_to <= bonusEndBlock) {
return _to.sub(_from);
return _to.sub(_from);
} else if (_from >= bonusEndBlock) {
} else if (_from >= bonusEndBlock) {
return 0;
return 0;
} else {
} else {
return bonusEndBlock.sub(_from);
return bonusEndBlock.sub(_from);
}
}
}
}
// View function to see pending Reward on frontend.
// View function to see pending Reward on frontend.
function pendingReward(address _user) external view returns (uint256) {
function pendingReward(address _user) external view returns (uint256) {
PoolInfo storage pool = poolInfo[0];
PoolInfo storage pool = poolInfo[0];
UserInfo storage user = userInfo[_user];
UserInfo storage user = userInfo[_user];
uint256 accRewardTokenPerShare = pool.accRewardTokenPerShare;
uint256 accRewardTokenPerShare = pool.accRewardTokenPerShare;
uint256 lpSupply = pool.lpToken.balanceOf(address(this));
uint256 lpSupply = pool.lpToken.balanceOf(address(this));
if (block.number > pool.lastRewardBlock && lpSupply != 0) {
if (block.number > pool.lastRewardBlock && lpSupply != 0) {
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
uint256 tokenReward = multiplier.mul(rewardPerBlock).mul(pool.allocPoint).div(totalAllocPoint);
uint256 tokenReward = multiplier.mul(rewardPerBlock).mul(pool.allocPoint).div(totalAllocPoint);
accRewardTokenPerShare = accRewardTokenPerShare.add(tokenReward.mul(1e12).div(lpSupply));
accRewardTokenPerShare = accRewardTokenPerShare.add(tokenReward.mul(1e12).div(lpSupply));
}
}
return user.amount.mul(accRewardTokenPerShare).div(1e12).sub(user.rewardDebt);
return user.amount.mul(accRewardTokenPerShare).div(1e12).sub(user.rewardDebt);
}
}
// Update reward variables of the given pool to be up-to-date.
// Update reward variables of the given pool to be up-to-date.
function updatePool(uint256 _pid) public {
function updatePool(uint256 _pid) public {
PoolInfo storage pool = poolInfo[_pid];
PoolInfo storage pool = poolInfo[_pid];
if (block.number <= pool.lastRewardBlock) {
if (block.number <= pool.lastRewardBlock) {
return;
return;
}
}
uint256 lpSupply = pool.lpToken.balanceOf(address(this));
uint256 lpSupply = pool.lpToken.balanceOf(address(this));
if (lpSupply == 0) {
if (lpSupply == 0) {
pool.lastRewardBlock = block.number;
pool.lastRewardBlock = block.number;
return;
return;
}
}
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
uint256 tokenReward = multiplier.mul(rewardPerBlock).mul(pool.allocPoint).div(totalAllocPoint);
uint256 tokenReward = multiplier.mul(rewardPerBlock).mul(pool.allocPoint).div(totalAllocPoint);
pool.accRewardTokenPerShare = pool.accRewardTokenPerShare.add(tokenReward.mul(1e12).div(lpSupply));
pool.accRewardTokenPerShare = pool.accRewardTokenPerShare.add(tokenReward.mul(1e12).div(lpSupply));
pool.lastRewardBlock = block.number;
pool.lastRewardBlock = block.number;
}
}
// Update reward variables for all pools. Be careful of gas spending!
// Update reward variables for all pools. Be careful of gas spending!
function massUpdatePools() public {
function massUpdatePools() public {
uint256 length = poolInfo.length;
uint256 length = poolInfo.length;
for (uint256 pid = 0; pid < length; ++pid) {
for (uint256 pid = 0; pid < length; ++pid) {
updatePool(pid);
updatePool(pid);
}
}
}
}
/// Deposit staking token into the contract to earn rewards.
/// Deposit staking token into the contract to earn rewards.
/// @dev Since this contract needs to be supplied with rewards we are
/// @dev Since this contract needs to be supplied with rewards we are
/// sending the balance of the contract if the pending rewards are higher
/// sending the balance of the contract if the pending rewards are higher
/// @param _amount The amount of staking tokens to deposit
/// @param _amount The amount of staking tokens to deposit
function deposit(uint256 _amount) public {
function deposit(uint256 _amount) public {
PoolInfo storage pool = poolInfo[0];
PoolInfo storage pool = poolInfo[0];
UserInfo storage user = userInfo[msg.sender];
UserInfo storage user = userInfo[msg.sender];
updatePool(0);
updatePool(0);
if (user.amount > 0) {
if (user.amount > 0) {
uint256 pending = user.amount.mul(pool.accRewardTokenPerShare).div(1e12).sub(user.rewardDebt);
uint256 pending = user.amount.mul(pool.accRewardTokenPerShare).div(1e12).sub(user.rewardDebt);
if(pending > 0) {
if(pending > 0) {
uint256 currentRewardBalance = rewardBalance();
uint256 currentRewardBalance = rewardBalance();
if(currentRewardBalance > 0) {
if(currentRewardBalance > 0) {
if(pending > currentRewardBalance) {
if(pending > currentRewardBalance) {
safeTransferReward(address(msg.sender), currentRewardBalance);
safeTransferReward(address(msg.sender), currentRewardBalance);
} else {
} else {
safeTransferReward(address(msg.sender), pending);
safeTransferReward(address(msg.sender), pending);
}
}
}
}
}
}
}
}
if(_amount > 0) {
if(_amount > 0) {
pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount);
pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount);
user.amount = user.amount.add(_amount);
user.amount = user.amount.add(_amount);
}
}
user.rewardDebt = user.amount.mul(pool.accRewardTokenPerShare).div(1e12);
user.rewardDebt = user.amount.mul(pool.accRewardTokenPerShare).div(1e12);
emit Deposit(msg.sender, _amount);
emit Deposit(msg.sender, _amount);
}
}
/// Withdraw rewards and/or staked tokens. Pass a 0 amount to withdraw only rewards
/// Withdraw rewards and/or staked tokens. Pass a 0 amount to withdraw only rewards
/// @param _amount The amount of staking tokens to withdraw
/// @param _amount The amount of staking tokens to withdraw
function withdraw(uint256 _amount) public {
function withdraw(uint256 _amount) public {
PoolInfo storage pool = poolInfo[0];
PoolInfo storage pool = poolInfo[0];
UserInfo storage user = userInfo[msg.sender];
UserInfo storage user = userInfo[msg.sender];
require(user.amount >= _amount, "withdraw: not good");
require(user.amount >= _amount, "withdraw: not good");
updatePool(0);
updatePool(0);
uint256 pending = user.amount.mul(pool.accRewardTokenPerShare).div(1e12).sub(user.rewardDebt);
uint256 pending = user.amount.mul(pool.accRewardTokenPerShare).div(1e12).sub(user.rewardDebt);
if(pending > 0) {
if(pending > 0) {
uint256 currentRewardBalance = rewardBalance();
uint256 currentRewardBalance = rewardBalance();
if(currentRewardBalance > 0) {
if(currentRewardBalance > 0) {
if(pending > currentRewardBalance) {
if(pending > currentRewardBalance) {
safeTransferReward(address(msg.sender), currentRewardBalance);
safeTransferReward(address(msg.sender), currentRewardBalance);
} else {
} else {
safeTransferReward(address(msg.sender), pending);
safeTransferReward(address(msg.sender), pending);
}
}
}
}
}
}
if(_amount > 0) {
if(_amount > 0) {
user.amount = user.amount.sub(_amount);
user.amount = user.amount.sub(_amount);
pool.lpToken.safeTransfer(address(msg.sender), _amount);
pool.lpToken.safeTransfer(address(msg.sender), _amount);
}
}
user.rewardDebt = user.amount.mul(pool.accRewardTokenPerShare).div(1e12);
user.rewardDebt = user.amount.mul(pool.accRewardTokenPerShare).div(1e12);
emit Withdraw(msg.sender, _amount);
emit Withdraw(msg.sender, _amount);
}
}
/// Obtain the reward balance of this contract
/// Obtain the reward balance of this contract
/// @return wei balace of conract
/// @return wei balace of conract
function rewardBalance() public view returns (uint256) {
function rewardBalance() public view returns (uint256) {
return rewardToken.balanceOf(address(this));
return rewardToken.balanceOf(address(this));
}
}
// Deposit Rewards into contract
// Deposit Rewards into contract
function depositRewards(uint256 _amount) external {
function depositRewards(uint256 _amount) external {
require(_amount > 0, 'Deposit value must be greater than 0.');
require(_amount > 0, 'Deposit value must be greater than 0.');
rewardToken.safeTransferFrom(address(msg.sender), address(this), _amount);
rewardToken.safeTransferFrom(address(msg.sender), address(this), _amount);
emit DepositRewards(_amount);
emit DepositRewards(_amount);
}
}
/// @param _to address to send reward token to
/// @param _to address to send reward token to
/// @param _amount value of reward token to transfer
/// @param _amount value of reward token to transfer
function safeTransferReward(address _to, uint256 _amount) internal {
function safeTransferReward(address _to, uint256 _amount) internal {
rewardToken.safeTransfer(_to, _amount);
rewardToken.safeTransfer(_to, _amount);
}
}
Copier
Copié
Copier
Copié
/* Admin Functions */
/// @param _rewardPerBlock The amount of reward tokens to be given per block
function setRewardPerBlock(uint256 _rewardPerBlock) external onlyOwner {
rewardPerBlock = _rewardPerBlock;
}
/// @param _bonusEndBlock The block when rewards will end
function setBonusEndBlock(uint256 _bonusEndBlock) external onlyOwner {
require(_bonusEndBlock > bonusEndBlock, 'new bonus end block must be greater than current');
bonusEndBlock = _bonusEndBlock;
}
/* Emergency Functions */
/* Emergency Functions */
// Withdraw without caring about rewards. EMERGENCY ONLY.
// Withdraw without caring about rewards. EMERGENCY ONLY.
function emergencyWithdraw() external {
function emergencyWithdraw() external {
PoolInfo storage pool = poolInfo[0];
PoolInfo storage pool = poolInfo[0];
UserInfo storage user = userInfo[msg.sender];
UserInfo storage user = userInfo[msg.sender];
pool.lpToken.safeTransfer(address(msg.sender), user.amount);
pool.lpToken.safeTransfer(address(msg.sender), user.amount);
user.amount = 0;
user.amount = 0;
user.rewardDebt = 0;
user.rewardDebt = 0;
emit EmergencyWithdraw(msg.sender, user.amount);
emit EmergencyWithdraw(msg.sender, user.amount);
}
}
// Withdraw reward. EMERGENCY ONLY.
// Withdraw reward. EMERGENCY ONLY.
function emergencyRewardWithdraw(uint256 _amount) external onlyOwner {
function emergencyRewardWithdraw(uint256 _amount) external onlyOwner {
require(_amount <= rewardBalance(), 'not enough rewards');
require(_amount <= rewardBalance(), 'not enough rewards');
// Withdraw rewards
// Withdraw rewards
safeTransferReward(address(msg.sender), _amount);
safeTransferReward(address(msg.sender), _amount);
emit EmergencyRewardWithdraw(msg.sender, _amount);
emit EmergencyRewardWithdraw(msg.sender, _amount);
}
}
}
}
Différences enregistrées
Texte d'origine
Ouvrir un fichier
pragma solidity 0.6.12; /* * ApeSwapFinance * App: https://apeswap.finance * Medium: https://ape-swap.medium.com * Twitter: https://twitter.com/ape_swap * Telegram: https://t.me/ape_swap * Announcements: https://t.me/ape_swap_news * GitHub: https://github.com/ApeSwapFinance */ import '@pancakeswap/pancake-swap-lib/contracts/math/SafeMath.sol'; import '@pancakeswap/pancake-swap-lib/contracts/token/BEP20/IBEP20.sol'; import '@pancakeswap/pancake-swap-lib/contracts/token/BEP20/SafeBEP20.sol'; import '@pancakeswap/pancake-swap-lib/contracts/access/Ownable.sol'; contract BEP20RewardApe is Ownable { using SafeMath for uint256; using SafeBEP20 for IBEP20; // Info of each user. struct UserInfo { uint256 amount; // How many LP tokens the user has provided. uint256 rewardDebt; // Reward debt. See explanation below. } // Info of each pool. struct PoolInfo { IBEP20 lpToken; // Address of LP token contract. uint256 allocPoint; // How many allocation points assigned to this pool. Rewards to distribute per block. uint256 lastRewardBlock; // Last block number that Rewards distribution occurs. uint256 accRewardTokenPerShare; // Accumulated Rewards per share, times 1e12. See below. } // The stake token IBEP20 public stakeToken; // The reward token IBEP20 public rewardToken; // Reward tokens created per block. uint256 public rewardPerBlock; // Info of each pool. PoolInfo[] public poolInfo; // Info of each user that stakes LP tokens. mapping (address => UserInfo) public userInfo; // Total allocation poitns. Must be the sum of all allocation points in all pools. uint256 private totalAllocPoint = 0; // The block number when Reward mining starts. uint256 public startBlock; // The block number when mining ends. uint256 public bonusEndBlock; event Deposit(address indexed user, uint256 amount); event DepositRewards(uint256 amount); event Withdraw(address indexed user, uint256 amount); event EmergencyWithdraw(address indexed user, uint256 amount); event EmergencyRewardWithdraw(address indexed user, uint256 amount); constructor( IBEP20 _stakeToken, IBEP20 _rewardToken, uint256 _rewardPerBlock, uint256 _startBlock, uint256 _bonusEndBlock ) public { stakeToken = _stakeToken; rewardToken = _rewardToken; rewardPerBlock = _rewardPerBlock; startBlock = _startBlock; bonusEndBlock = _bonusEndBlock; // staking pool poolInfo.push(PoolInfo({ lpToken: _stakeToken, allocPoint: 1000, lastRewardBlock: startBlock, accRewardTokenPerShare: 0 })); totalAllocPoint = 1000; } // Return reward multiplier over the given _from to _to block. function getMultiplier(uint256 _from, uint256 _to) public view returns (uint256) { if (_to <= bonusEndBlock) { return _to.sub(_from); } else if (_from >= bonusEndBlock) { return 0; } else { return bonusEndBlock.sub(_from); } } // View function to see pending Reward on frontend. function pendingReward(address _user) external view returns (uint256) { PoolInfo storage pool = poolInfo[0]; UserInfo storage user = userInfo[_user]; uint256 accRewardTokenPerShare = pool.accRewardTokenPerShare; uint256 lpSupply = pool.lpToken.balanceOf(address(this)); if (block.number > pool.lastRewardBlock && lpSupply != 0) { uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number); uint256 tokenReward = multiplier.mul(rewardPerBlock).mul(pool.allocPoint).div(totalAllocPoint); accRewardTokenPerShare = accRewardTokenPerShare.add(tokenReward.mul(1e12).div(lpSupply)); } return user.amount.mul(accRewardTokenPerShare).div(1e12).sub(user.rewardDebt); } // Update reward variables of the given pool to be up-to-date. 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 multiplier = getMultiplier(pool.lastRewardBlock, block.number); uint256 tokenReward = multiplier.mul(rewardPerBlock).mul(pool.allocPoint).div(totalAllocPoint); pool.accRewardTokenPerShare = pool.accRewardTokenPerShare.add(tokenReward.mul(1e12).div(lpSupply)); pool.lastRewardBlock = block.number; } // Update reward variables for all pools. Be careful of gas spending! function massUpdatePools() public { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { updatePool(pid); } } /// Deposit staking token into the contract to earn rewards. /// @dev Since this contract needs to be supplied with rewards we are /// sending the balance of the contract if the pending rewards are higher /// @param _amount The amount of staking tokens to deposit function deposit(uint256 _amount) public { PoolInfo storage pool = poolInfo[0]; UserInfo storage user = userInfo[msg.sender]; updatePool(0); if (user.amount > 0) { uint256 pending = user.amount.mul(pool.accRewardTokenPerShare).div(1e12).sub(user.rewardDebt); if(pending > 0) { uint256 currentRewardBalance = rewardBalance(); if(currentRewardBalance > 0) { if(pending > currentRewardBalance) { safeTransferReward(address(msg.sender), currentRewardBalance); } else { safeTransferReward(address(msg.sender), pending); } } } } if(_amount > 0) { pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount); user.amount = user.amount.add(_amount); } user.rewardDebt = user.amount.mul(pool.accRewardTokenPerShare).div(1e12); emit Deposit(msg.sender, _amount); } /// Withdraw rewards and/or staked tokens. Pass a 0 amount to withdraw only rewards /// @param _amount The amount of staking tokens to withdraw function withdraw(uint256 _amount) public { PoolInfo storage pool = poolInfo[0]; UserInfo storage user = userInfo[msg.sender]; require(user.amount >= _amount, "withdraw: not good"); updatePool(0); uint256 pending = user.amount.mul(pool.accRewardTokenPerShare).div(1e12).sub(user.rewardDebt); if(pending > 0) { uint256 currentRewardBalance = rewardBalance(); if(currentRewardBalance > 0) { if(pending > currentRewardBalance) { safeTransferReward(address(msg.sender), currentRewardBalance); } else { safeTransferReward(address(msg.sender), pending); } } } if(_amount > 0) { user.amount = user.amount.sub(_amount); pool.lpToken.safeTransfer(address(msg.sender), _amount); } user.rewardDebt = user.amount.mul(pool.accRewardTokenPerShare).div(1e12); emit Withdraw(msg.sender, _amount); } /// Obtain the reward balance of this contract /// @return wei balace of conract function rewardBalance() public view returns (uint256) { return rewardToken.balanceOf(address(this)); } // Deposit Rewards into contract function depositRewards(uint256 _amount) external { require(_amount > 0, 'Deposit value must be greater than 0.'); rewardToken.safeTransferFrom(address(msg.sender), address(this), _amount); emit DepositRewards(_amount); } /// @param _to address to send reward token to /// @param _amount value of reward token to transfer function safeTransferReward(address _to, uint256 _amount) internal { rewardToken.safeTransfer(_to, _amount); } /* Emergency Functions */ // Withdraw without caring about rewards. EMERGENCY ONLY. function emergencyWithdraw() external { PoolInfo storage pool = poolInfo[0]; UserInfo storage user = userInfo[msg.sender]; pool.lpToken.safeTransfer(address(msg.sender), user.amount); user.amount = 0; user.rewardDebt = 0; emit EmergencyWithdraw(msg.sender, user.amount); } // Withdraw reward. EMERGENCY ONLY. function emergencyRewardWithdraw(uint256 _amount) external onlyOwner { require(_amount <= rewardBalance(), 'not enough rewards'); // Withdraw rewards safeTransferReward(address(msg.sender), _amount); emit EmergencyRewardWithdraw(msg.sender, _amount); } }
Texte modifié
Ouvrir un fichier
pragma solidity 0.6.12; /* * ApeSwapFinance * App: https://apeswap.finance * Medium: https://ape-swap.medium.com * Twitter: https://twitter.com/ape_swap * Telegram: https://t.me/ape_swap * Announcements: https://t.me/ape_swap_news * GitHub: https://github.com/ApeSwapFinance */ import '@pancakeswap/pancake-swap-lib/contracts/math/SafeMath.sol'; import '@pancakeswap/pancake-swap-lib/contracts/token/BEP20/IBEP20.sol'; import '@pancakeswap/pancake-swap-lib/contracts/token/BEP20/SafeBEP20.sol'; import '@pancakeswap/pancake-swap-lib/contracts/access/Ownable.sol'; contract BEP20RewardApeV2 is Ownable { using SafeMath for uint256; using SafeBEP20 for IBEP20; // Info of each user. struct UserInfo { uint256 amount; // How many LP tokens the user has provided. uint256 rewardDebt; // Reward debt. See explanation below. } // Info of each pool. struct PoolInfo { IBEP20 lpToken; // Address of LP token contract. uint256 allocPoint; // How many allocation points assigned to this pool. Rewards to distribute per block. uint256 lastRewardBlock; // Last block number that Rewards distribution occurs. uint256 accRewardTokenPerShare; // Accumulated Rewards per share, times 1e12. See below. } // The stake token IBEP20 public stakeToken; // The reward token IBEP20 public rewardToken; // Reward tokens created per block. uint256 public rewardPerBlock; // Info of each pool. PoolInfo[] public poolInfo; // Info of each user that stakes LP tokens. mapping (address => UserInfo) public userInfo; // Total allocation poitns. Must be the sum of all allocation points in all pools. uint256 private totalAllocPoint = 0; // The block number when Reward mining starts. uint256 public startBlock; // The block number when mining ends. uint256 public bonusEndBlock; event Deposit(address indexed user, uint256 amount); event DepositRewards(uint256 amount); event Withdraw(address indexed user, uint256 amount); event EmergencyWithdraw(address indexed user, uint256 amount); event EmergencyRewardWithdraw(address indexed user, uint256 amount); constructor( IBEP20 _stakeToken, IBEP20 _rewardToken, uint256 _rewardPerBlock, uint256 _startBlock, uint256 _bonusEndBlock ) public { stakeToken = _stakeToken; rewardToken = _rewardToken; rewardPerBlock = _rewardPerBlock; startBlock = _startBlock; bonusEndBlock = _bonusEndBlock; // staking pool poolInfo.push(PoolInfo({ lpToken: _stakeToken, allocPoint: 1000, lastRewardBlock: startBlock, accRewardTokenPerShare: 0 })); totalAllocPoint = 1000; } // Return reward multiplier over the given _from to _to block. function getMultiplier(uint256 _from, uint256 _to) public view returns (uint256) { if (_to <= bonusEndBlock) { return _to.sub(_from); } else if (_from >= bonusEndBlock) { return 0; } else { return bonusEndBlock.sub(_from); } } // View function to see pending Reward on frontend. function pendingReward(address _user) external view returns (uint256) { PoolInfo storage pool = poolInfo[0]; UserInfo storage user = userInfo[_user]; uint256 accRewardTokenPerShare = pool.accRewardTokenPerShare; uint256 lpSupply = pool.lpToken.balanceOf(address(this)); if (block.number > pool.lastRewardBlock && lpSupply != 0) { uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number); uint256 tokenReward = multiplier.mul(rewardPerBlock).mul(pool.allocPoint).div(totalAllocPoint); accRewardTokenPerShare = accRewardTokenPerShare.add(tokenReward.mul(1e12).div(lpSupply)); } return user.amount.mul(accRewardTokenPerShare).div(1e12).sub(user.rewardDebt); } // Update reward variables of the given pool to be up-to-date. 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 multiplier = getMultiplier(pool.lastRewardBlock, block.number); uint256 tokenReward = multiplier.mul(rewardPerBlock).mul(pool.allocPoint).div(totalAllocPoint); pool.accRewardTokenPerShare = pool.accRewardTokenPerShare.add(tokenReward.mul(1e12).div(lpSupply)); pool.lastRewardBlock = block.number; } // Update reward variables for all pools. Be careful of gas spending! function massUpdatePools() public { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { updatePool(pid); } } /// Deposit staking token into the contract to earn rewards. /// @dev Since this contract needs to be supplied with rewards we are /// sending the balance of the contract if the pending rewards are higher /// @param _amount The amount of staking tokens to deposit function deposit(uint256 _amount) public { PoolInfo storage pool = poolInfo[0]; UserInfo storage user = userInfo[msg.sender]; updatePool(0); if (user.amount > 0) { uint256 pending = user.amount.mul(pool.accRewardTokenPerShare).div(1e12).sub(user.rewardDebt); if(pending > 0) { uint256 currentRewardBalance = rewardBalance(); if(currentRewardBalance > 0) { if(pending > currentRewardBalance) { safeTransferReward(address(msg.sender), currentRewardBalance); } else { safeTransferReward(address(msg.sender), pending); } } } } if(_amount > 0) { pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount); user.amount = user.amount.add(_amount); } user.rewardDebt = user.amount.mul(pool.accRewardTokenPerShare).div(1e12); emit Deposit(msg.sender, _amount); } /// Withdraw rewards and/or staked tokens. Pass a 0 amount to withdraw only rewards /// @param _amount The amount of staking tokens to withdraw function withdraw(uint256 _amount) public { PoolInfo storage pool = poolInfo[0]; UserInfo storage user = userInfo[msg.sender]; require(user.amount >= _amount, "withdraw: not good"); updatePool(0); uint256 pending = user.amount.mul(pool.accRewardTokenPerShare).div(1e12).sub(user.rewardDebt); if(pending > 0) { uint256 currentRewardBalance = rewardBalance(); if(currentRewardBalance > 0) { if(pending > currentRewardBalance) { safeTransferReward(address(msg.sender), currentRewardBalance); } else { safeTransferReward(address(msg.sender), pending); } } } if(_amount > 0) { user.amount = user.amount.sub(_amount); pool.lpToken.safeTransfer(address(msg.sender), _amount); } user.rewardDebt = user.amount.mul(pool.accRewardTokenPerShare).div(1e12); emit Withdraw(msg.sender, _amount); } /// Obtain the reward balance of this contract /// @return wei balace of conract function rewardBalance() public view returns (uint256) { return rewardToken.balanceOf(address(this)); } // Deposit Rewards into contract function depositRewards(uint256 _amount) external { require(_amount > 0, 'Deposit value must be greater than 0.'); rewardToken.safeTransferFrom(address(msg.sender), address(this), _amount); emit DepositRewards(_amount); } /// @param _to address to send reward token to /// @param _amount value of reward token to transfer function safeTransferReward(address _to, uint256 _amount) internal { rewardToken.safeTransfer(_to, _amount); } /* Admin Functions */ /// @param _rewardPerBlock The amount of reward tokens to be given per block function setRewardPerBlock(uint256 _rewardPerBlock) external onlyOwner { rewardPerBlock = _rewardPerBlock; } /// @param _bonusEndBlock The block when rewards will end function setBonusEndBlock(uint256 _bonusEndBlock) external onlyOwner { require(_bonusEndBlock > bonusEndBlock, 'new bonus end block must be greater than current'); bonusEndBlock = _bonusEndBlock; } /* Emergency Functions */ // Withdraw without caring about rewards. EMERGENCY ONLY. function emergencyWithdraw() external { PoolInfo storage pool = poolInfo[0]; UserInfo storage user = userInfo[msg.sender]; pool.lpToken.safeTransfer(address(msg.sender), user.amount); user.amount = 0; user.rewardDebt = 0; emit EmergencyWithdraw(msg.sender, user.amount); } // Withdraw reward. EMERGENCY ONLY. function emergencyRewardWithdraw(uint256 _amount) external onlyOwner { require(_amount <= rewardBalance(), 'not enough rewards'); // Withdraw rewards safeTransferReward(address(msg.sender), _amount); emit EmergencyRewardWithdraw(msg.sender, _amount); } }
Trouver la différence