About link description
YIELD App (YLD) is a cryptocurrency and operates on the Ethereum platform. YIELD App has a current supply of 119,871,747 with 112,508,581.49782473 in circulation. The last known price of YIELD App is 0.36227137 USD and is up 0.12 over the last 24 hours. It is currently trading on 10 active market(s) with $272,382.48 traded over the last 24 hours. More information can be found at https://www.yield.app/.
Identical Contracts
The following contracts have identical source code.
Stats
Public Functions
43
Event Types
9
Code Size
86,874 bytes
Library Use
Uses SafeMathUpgradeable for uint256.
Uses EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet.
Events (9) keyboard_arrow_up
Structs (5) keyboard_arrow_up
Constants (4) keyboard_arrow_up
State Variables (34) keyboard_arrow_up
Functions
hasRole keyboard_arrow_up
getRoleMemberCount keyboard_arrow_up
getRoleMember keyboard_arrow_up
getRoleAdmin keyboard_arrow_up
grantRole keyboard_arrow_up
Requirements help
null
Source Code
function grantRole(bytes32 role, address account) public virtual {
require(
hasRole(_roles[role].adminRole, _msgSender()),
"AccessControl: sender must be an admin to grant"
);
_grantRole(role, account);
}
revokeRole keyboard_arrow_up
Requirements help
null
Source Code
function revokeRole(bytes32 role, address account) public virtual {
require(
hasRole(_roles[role].adminRole, _msgSender()),
"AccessControl: sender must be an admin to revoke"
);
_revokeRole(role, account);
}
renounceRole keyboard_arrow_up
Requirements help
Source Code
function renounceRole(bytes32 role, address account) public virtual {
require(
account == _msgSender(),
"AccessControl: can only renounce roles for self"
);
_revokeRole(role, account);
}
initialize keyboard_arrow_up
Modifiers help
initializer checks for the following:
One or more of the following:
-_initialized must not be true - ORnull - OR_initializing must be true
Source Code
function initialize(address _manager, address _migrator) public initializer {
_setupRole(MANAGER_ROLE, _manager);
_setupRole(MIGRATOR_ROLE, _migrator);
init_ = false;
}
sessionsOf_ keyboard_arrow_up
stake keyboard_arrow_up
Modifiers help
pausable checks for the following:
Requirements help
Source Code
function stake(uint256 amount, uint256 stakingDays) external pausable {
require(stakingDays != 0, "Staking: Staking days < 1");
require(stakingDays <= 5555, "Staking: Staking days > 5555");
//call stake internal method
stakeInternal(amount, stakingDays, msg.sender);
//on stake axion gets burned
IToken(addresses.mainToken).burn(msg.sender, amount);
}
externalStake keyboard_arrow_up
Modifiers help
onlyExternalStaker checks for the following:
null
pausable checks for the following:
Requirements help
Source Code
function externalStake(
uint256 amount,
uint256 stakingDays,
address staker
) external override onlyExternalStaker pausable {
require(stakingDays != 0, "Staking: Staking days < 1");
require(stakingDays <= 5555, "Staking: Staking days > 5555");
stakeInternal(amount, stakingDays, staker);
}
calculateStakingInterest keyboard_arrow_up
Source Code
function calculateStakingInterest(
uint256 firstPayout,
uint256 lastPayout,
uint256 shares
) public view returns (uint256) {
uint256 stakingInterest;
//calculate lastIndex as minimum of lastPayout from stake session and current day (payouts.length).
uint256 lastIndex = MathUpgradeable.min(payouts.length, lastPayout);
for (uint256 i = firstPayout; i < lastIndex; i++) {
uint256 payout = payouts[i].payout.mul(shares).div(
payouts[i].sharesTotalSupply
);
stakingInterest = stakingInterest.add(payout);
}
return stakingInterest;
}
unstake keyboard_arrow_up
Modifiers help
pausable checks for the following:
Requirements help
Source Code
function unstake(uint256 sessionId) external pausable {
Session storage session = sessionDataOf[msg.sender][sessionId];
//ensure the stake hasn't been withdrawn before
require(
session.shares != 0 && session.withdrawn == false,
"Staking: Stake withdrawn or not set"
);
uint256 actualEnd = now;
//calculate the amount the stake earned; to be paid
uint256 amountOut = unstakeInternal(session, sessionId, actualEnd);
// To account
_initPayout(msg.sender, amountOut);
}
unstakeV1 keyboard_arrow_up
Modifiers help
pausable checks for the following:
Requirements help
Source Code
function unstakeV1(uint256 sessionId) external pausable {
//lastSessionIdv1 is the last stake ID from v1 layer
require(sessionId <= lastSessionIdV1, "Staking: Invalid sessionId");
Session storage session = sessionDataOf[msg.sender][sessionId];
// Unstaked already
require(
session.shares == 0 && session.withdrawn == false,
"Staking: Stake withdrawn"
);
(
uint256 amount,
uint256 start,
uint256 end,
uint256 shares,
uint256 firstPayout
) = stakingV1.sessionDataOf(msg.sender, sessionId);
// Unstaked in v1 / doesn't exist
require(shares != 0, "Staking: Stake withdrawn or not set");
uint256 stakingDays = (end - start) / stepTimestamp;
uint256 lastPayout = stakingDays + firstPayout;
uint256 actualEnd = now;
//calculate amount to be paid
uint256 amountOut = unstakeV1Internal(
sessionId,
amount,
start,
end,
actualEnd,
shares,
firstPayout,
lastPayout
);
// To account
_initPayout(msg.sender, amountOut);
}
getAmountOutAndPenalty keyboard_arrow_up
Parameters help
Source Code
function getAmountOutAndPenalty(
uint256 amount,
uint256 start,
uint256 end,
uint256 stakingInterest
) public view returns (uint256, uint256) {
uint256 stakingSeconds = end.sub(start);
uint256 stakingDays = stakingSeconds.div(stepTimestamp);
uint256 secondsStaked = now.sub(start);
uint256 daysStaked = secondsStaked.div(stepTimestamp);
uint256 amountAndInterest = amount.add(stakingInterest);
// Early
if (stakingDays > daysStaked) {
uint256 payOutAmount = amountAndInterest.mul(secondsStaked).div(
stakingSeconds
);
uint256 earlyUnstakePenalty = amountAndInterest.sub(payOutAmount);
return (payOutAmount, earlyUnstakePenalty);
// In time
} else if (daysStaked < stakingDays.add(14)) {
return (amountAndInterest, 0);
// Late
} else if (daysStaked < stakingDays.add(714)) {
return (amountAndInterest, 0);
/** Remove late penalties for now */
// uint256 daysAfterStaking = daysStaked - stakingDays;
// uint256 payOutAmount =
// amountAndInterest.mul(uint256(714).sub(daysAfterStaking)).div(
// 700
// );
// uint256 lateUnstakePenalty = amountAndInterest.sub(payOutAmount);
// return (payOutAmount, lateUnstakePenalty);
// Nothing
} else {
return (0, amountAndInterest);
}
}
makePayout keyboard_arrow_up
Parameters help
This function has no parameters.
Requirements help
Source Code
function makePayout() public {
require(now >= nextPayoutCall, "Staking: Wrong payout time");
uint256 payout = _getPayout();
payouts.push(Payout({payout: payout, sharesTotalSupply: sharesTotalSupply}));
nextPayoutCall = nextPayoutCall.add(stepTimestamp);
//call updateShareRate once a day as sharerate increases based on the daily Payout amount
updateShareRate(payout);
emit MakePayout(payout, sharesTotalSupply, now);
}
restake keyboard_arrow_up
Modifiers help
pausable checks for the following:
Requirements help
Source Code
function restake(
uint256 sessionId,
uint256 stakingDays,
uint256 topup
) external pausable {
require(stakingDays != 0, "Staking: Staking days < 1");
require(stakingDays <= 5555, "Staking: Staking days > 5555");
Session storage session = sessionDataOf[msg.sender][sessionId];
require(
session.shares != 0 && session.withdrawn == false,
"Staking: Stake withdrawn/invalid"
);
uint256 actualEnd = now;
require(session.end <= actualEnd, "Staking: Stake not mature");
uint256 amountOut = unstakeInternal(session, sessionId, actualEnd);
if (topup != 0) {
IToken(addresses.mainToken).burn(msg.sender, topup);
amountOut = amountOut.add(topup);
}
stakeInternal(amountOut, stakingDays, msg.sender);
}
restakeV1 keyboard_arrow_up
Modifiers help
pausable checks for the following:
Requirements help
Source Code
function restakeV1(
uint256 sessionId,
uint256 stakingDays,
uint256 topup
) external pausable {
require(sessionId <= lastSessionIdV1, "Staking: Invalid sessionId");
require(stakingDays != 0, "Staking: Staking days < 1");
require(stakingDays <= 5555, "Staking: Staking days > 5555");
Session storage session = sessionDataOf[msg.sender][sessionId];
require(
session.shares == 0 && session.withdrawn == false,
"Staking: Stake withdrawn"
);
(
uint256 amount,
uint256 start,
uint256 end,
uint256 shares,
uint256 firstPayout
) = stakingV1.sessionDataOf(msg.sender, sessionId);
// Unstaked in v1 / doesn't exist
require(shares != 0, "Staking: Stake withdrawn");
uint256 actualEnd = now;
require(end <= actualEnd, "Staking: Stake not mature");
uint256 sessionStakingDays = (end - start) / stepTimestamp;
uint256 lastPayout = sessionStakingDays + firstPayout;
uint256 amountOut = unstakeV1Internal(
sessionId,
amount,
start,
end,
actualEnd,
shares,
firstPayout,
lastPayout
);
if (topup != 0) {
IToken(addresses.mainToken).burn(msg.sender, topup);
amountOut = amountOut.add(topup);
}
stakeInternal(amountOut, stakingDays, msg.sender);
}
withdrawDivToken keyboard_arrow_up
getTokenInterestEarned keyboard_arrow_up
Source Code
function getTokenInterestEarned(address accountAddress, address tokenAddress)
external
view
returns (uint256)
{
return
getTokenInterestEarnedInternal(
accountAddress,
tokenAddress,
totalSharesOf[accountAddress]
);
}
setTotalSharesOfAccount keyboard_arrow_up
Requirements help
Source Code
function setTotalSharesOfAccount(address _address) external {
setTotalSharesOfAccountInternal(_address);
}
updateTokenPricePerShare keyboard_arrow_up
Parameters help
Modifiers help
onlyAuction checks for the following:
Source Code
function updateTokenPricePerShare(
address payable bidderAddress,
address payable originAddress,
address tokenAddress,
uint256 amountBought
) external payable override onlyAuction {
// uint256 amountForBidder = amountBought.mul(10526315789473685).div(1e17);
uint256 amountForOrigin = amountBought.mul(5).div(100); //5% fee goes to dev
uint256 amountForBidder = amountBought.mul(10).div(100); //10% is being returned to bidder
uint256 amountForDivs = amountBought.sub(amountForOrigin).sub(
amountForBidder
); //remaining is the actual amount that was used to buy the token
if (tokenAddress != address(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF)) {
IERC20Upgradeable(tokenAddress).transfer(
bidderAddress, //pay the bidder the 10%
amountForBidder
);
IERC20Upgradeable(tokenAddress).transfer(
originAddress, //pay the dev fee the 5%
amountForOrigin
);
} else {
//if token is ETH we use the transfer function
bidderAddress.transfer(amountForBidder);
originAddress.transfer(amountForOrigin);
}
tokenPricePerShare[tokenAddress] = tokenPricePerShare[tokenAddress].add( //increase the token price per share with the amount bought divided by the total Vca registered shares
amountForDivs.mul(10**36).div(totalVcaRegisteredShares)
);
}
addDivToken keyboard_arrow_up
Modifiers help
onlyAuction checks for the following:
Source Code
function addDivToken(address tokenAddress) external override onlyAuction {
if (!divTokens.contains(tokenAddress)) {
//make sure the token is not already added
divTokens.add(tokenAddress);
}
}
setShareRateScalingFactor keyboard_arrow_up
Modifiers help
onlyManager checks for the following:
null
Source Code
function setShareRateScalingFactor(uint256 _scalingFactor)
external
onlyManager
{
shareRateScalingFactor = _scalingFactor;
}
maxShare keyboard_arrow_up
Modifiers help
pausable checks for the following:
Requirements help
Source Code
function maxShare(uint256 sessionId) external pausable {
Session storage session = sessionDataOf[msg.sender][sessionId];
require(
session.shares != 0 && session.withdrawn == false,
"STAKING: Stake withdrawn or not set"
);
(
uint256 newStart,
uint256 newEnd,
uint256 newAmount,
uint256 newShares
) = maxShareUpgrade(
session.firstPayout,
session.lastPayout,
session.shares,
session.amount
);
addBPDMaxShares(
session.shares,
session.start,
session.end,
newShares,
newStart,
newEnd
);
maxShareInternal(
sessionId,
session.shares,
newShares,
session.amount,
newAmount,
newStart,
newEnd
);
sessionDataOf[msg.sender][sessionId].amount = newAmount;
sessionDataOf[msg.sender][sessionId].end = newEnd;
sessionDataOf[msg.sender][sessionId].start = newStart;
sessionDataOf[msg.sender][sessionId].shares = newShares;
sessionDataOf[msg.sender][sessionId].firstPayout = payouts.length;
sessionDataOf[msg.sender][sessionId].lastPayout = payouts.length + 5555;
}
maxShareV1 keyboard_arrow_up
Modifiers help
pausable checks for the following:
Requirements help
Source Code
function maxShareV1(uint256 sessionId) external pausable {
require(sessionId <= lastSessionIdV1, "STAKING: Invalid sessionId");
Session storage session = sessionDataOf[msg.sender][sessionId];
require(
session.shares == 0 && session.withdrawn == false,
"STAKING: Stake withdrawn"
);
(
uint256 amount,
uint256 start,
uint256 end,
uint256 shares,
uint256 firstPayout
) = stakingV1.sessionDataOf(msg.sender, sessionId);
uint256 stakingDays = (end - start) / stepTimestamp;
uint256 lastPayout = stakingDays + firstPayout;
(
uint256 newStart,
uint256 newEnd,
uint256 newAmount,
uint256 newShares
) = maxShareUpgrade(firstPayout, lastPayout, shares, amount);
addBPDMaxShares(shares, start, end, newShares, newStart, newEnd);
maxShareInternal(
sessionId,
shares,
newShares,
amount,
newAmount,
newStart,
newEnd
);
sessionDataOf[msg.sender][sessionId] = Session({
amount: newAmount,
start: newStart,
end: newEnd,
shares: newShares,
firstPayout: payouts.length,
lastPayout: payouts.length + 5555,
withdrawn: false,
payout: 0
});
sessionsOf[msg.sender].push(sessionId);
}
calculateStepsFromStart keyboard_arrow_up
setMaxShareEventActive keyboard_arrow_up
getMaxShareEventActive keyboard_arrow_up
setMaxShareMaxDays keyboard_arrow_up
Modifiers help
onlyManager checks for the following:
null
Source Code
function setMaxShareMaxDays(uint16 _maxShareMaxDays) external onlyManager {
maxShareMaxDays = _maxShareMaxDays;
}
setTotalVcaRegisteredShares keyboard_arrow_up
setPaused keyboard_arrow_up
Requirements help
One or more of the following:
-null - ORnull
Source Code
function setPaused(bool _paused) external {
require(
hasRole(MIGRATOR_ROLE, msg.sender) || hasRole(MANAGER_ROLE, msg.sender),
"STAKING: User must be manager or migrator"
);
paused = _paused;
}
getPaused keyboard_arrow_up
getMaxShareMaxDays keyboard_arrow_up
setupRole keyboard_arrow_up
getDivTokens keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function getDivTokens() external view returns (address[] memory) {
address[] memory divTokenAddresses = new address[](divTokens.length());
for (uint8 i = 0; i < divTokens.length(); i++) {
divTokenAddresses[i] = divTokens.at(i);
}
return divTokenAddresses;
}
getTotalSharesOf keyboard_arrow_up
getTotalVcaRegisteredShares keyboard_arrow_up
getIsVCARegistered keyboard_arrow_up
setBPDPools keyboard_arrow_up
Modifiers help
onlyMigrator checks for the following:
null
Source Code
function setBPDPools(
uint128[5] calldata poolAmount,
uint128[5] calldata poolShares
) external onlyMigrator {
for (uint8 i = 0; i < poolAmount.length; i++) {
bpd128.pool[i] = poolAmount[i];
bpd128.shares[i] = poolShares[i];
}
}
findBPDEligible keyboard_arrow_up
calcBPD keyboard_arrow_up
Source Code
function calcBPD(
uint256 start,
uint256 end,
uint256 shares
) public view returns (uint256) {
uint16[2] memory bpdInterval = findBPDs(start, end);
return calcBPDOnWithdraw(shares, bpdInterval);
}
Internal Functions
Internal functions are parts of the contract that can't be used directly, but instead are used by the public functions listed above.
internal Staking.stakeInternal keyboard_arrow_up
Source Code
function stakeInternal(
uint256 amount,
uint256 stakingDays,
address staker
) internal {
//once a day we need to call makePayout which takes the interest earned for the last day and adds it into the payout array
if (now >= nextPayoutCall) makePayout();
//ensure the user is registered for VCA if not call it
if (isVcaRegistered[staker] == false) setTotalSharesOfAccountInternal(staker);
//time of staking start is now
uint256 start = now;
//time of stake end is now + number of days * stepTimestamp which is 24 hours
uint256 end = now.add(stakingDays.mul(stepTimestamp));
//increase the last stake ID
lastSessionId = lastSessionId.add(1);
// restake-event feature
if (stakingDays >= 350) {
amount = amount.add(amount.mul(stakingDays.div(350).add(5)).div(100)); // multiply by percent divide by 100
}
stakeInternalCommon(
lastSessionId,
amount,
start,
end,
stakingDays,
payouts.length,
staker
);
}
internal Staking._initPayout keyboard_arrow_up
internal Staking._getPayout keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function _getPayout() internal returns (uint256) {
//amountTokenInDay - AXN from auction buybacks goes into the staking contract
uint256 amountTokenInDay = IERC20Upgradeable(addresses.mainToken).balanceOf(
address(this)
);
globalPayin = globalPayin.add(amountTokenInDay);
if (globalPayin > globalPayout) {
globalPayin = globalPayin.sub(globalPayout);
globalPayout = 0;
} else {
globalPayin = 0;
globalPayout = 0;
}
uint256 currentTokenTotalSupply = (
IERC20Upgradeable(addresses.mainToken).totalSupply()
)
.add(globalPayin);
IToken(addresses.mainToken).burn(address(this), amountTokenInDay);
//we add 8% inflation
uint256 inflation = uint256(8)
.mul(currentTokenTotalSupply.add(totalStakedAmount))
.div(36500);
globalPayin = globalPayin.add(inflation);
return amountTokenInDay.add(inflation);
}
internal Staking._getStakersSharesAmount keyboard_arrow_up
Source Code
function _getStakersSharesAmount(
uint256 amount,
uint256 start,
uint256 end
) internal view returns (uint256) {
uint256 stakingDays = (end.sub(start)).div(stepTimestamp);
uint256 numerator = amount.mul(uint256(1819).add(stakingDays));
uint256 denominator = uint256(1820).mul(shareRate);
return (numerator).mul(1e18).div(denominator);
}
internal Staking._getShareRate keyboard_arrow_up
Parameters help
Source Code
function _getShareRate(
uint256 amount,
uint256 shares,
uint256 start,
uint256 end,
uint256 stakingInterest
) internal view returns (uint256) {
uint256 stakingDays = (end.sub(start)).div(stepTimestamp);
uint256 numerator = (amount.add(stakingInterest)).mul(
uint256(1819).add(stakingDays)
);
uint256 denominator = uint256(1820).mul(shares);
return (numerator).mul(1e18).div(denominator);
}
internal Staking.unstakeInternal keyboard_arrow_up
Source Code
function unstakeInternal(
Session storage session,
uint256 sessionId,
uint256 actualEnd
) internal returns (uint256) {
uint256 amountOut = unstakeInternalCommon(
sessionId,
session.amount,
session.start,
session.end,
actualEnd,
session.shares,
session.firstPayout,
session.lastPayout
);
session.end = actualEnd;
session.withdrawn = true;
session.payout = amountOut;
return amountOut;
}
internal Staking.unstakeV1Internal keyboard_arrow_up
Parameters help
Source Code
function unstakeV1Internal(
uint256 sessionId,
uint256 amount,
uint256 start,
uint256 end,
uint256 actualEnd,
uint256 shares,
uint256 firstPayout,
uint256 lastPayout
) internal returns (uint256) {
uint256 amountOut = unstakeInternalCommon(
sessionId,
amount,
start,
end,
actualEnd,
shares,
firstPayout,
lastPayout
);
sessionDataOf[msg.sender][sessionId] = Session({
amount: amount,
start: start,
end: actualEnd,
shares: shares,
firstPayout: firstPayout,
lastPayout: lastPayout,
withdrawn: true,
payout: amountOut
});
sessionsOf[msg.sender].push(sessionId);
return amountOut;
}
internal Staking.unstakeInternalCommon keyboard_arrow_up
Parameters help
Source Code
function unstakeInternalCommon(
uint256 sessionId,
uint256 amount,
uint256 start,
uint256 end,
uint256 actualEnd,
uint256 shares,
uint256 firstPayout,
uint256 lastPayout
) internal returns (uint256) {
if (now >= nextPayoutCall) makePayout();
if (isVcaRegistered[msg.sender] == false)
setTotalSharesOfAccountInternal(msg.sender);
uint256 stakingInterest = calculateStakingInterest(
firstPayout,
lastPayout,
shares
);
sharesTotalSupply = sharesTotalSupply.sub(shares);
totalStakedAmount = totalStakedAmount.sub(amount);
totalVcaRegisteredShares = totalVcaRegisteredShares.sub(shares);
uint256 oldTotalSharesOf = totalSharesOf[msg.sender];
totalSharesOf[msg.sender] = totalSharesOf[msg.sender].sub(shares);
rebalance(msg.sender, oldTotalSharesOf);
(uint256 amountOut, uint256 penalty) = getAmountOutAndPenalty(
amount,
start,
end,
stakingInterest
);
// add bpd to amount amountOut if stakingDays >= basePeriod
uint256 stakingDays = (actualEnd - start) / stepTimestamp;
if (stakingDays >= basePeriod) {
// We use "Actual end" so that if a user tries to withdraw their BPD early they don't get the shares
uint256 bpdAmount = calcBPD(
start,
actualEnd < end ? actualEnd : end,
shares
);
amountOut = amountOut.add(bpdAmount);
}
// To auction
if (penalty != 0) {
_initPayout(addresses.auction, penalty);
IAuction(addresses.auction).callIncomeDailyTokensTrigger(penalty);
}
emit Unstake(msg.sender, sessionId, amountOut, start, actualEnd, shares);
return amountOut;
}
internal Staking.stakeInternalCommon keyboard_arrow_up
Parameters help
Source Code
function stakeInternalCommon(
uint256 sessionId,
uint256 amount,
uint256 start,
uint256 end,
uint256 stakingDays,
uint256 firstPayout,
address staker
) internal {
uint256 shares = _getStakersSharesAmount(amount, start, end);
sharesTotalSupply = sharesTotalSupply.add(shares);
totalStakedAmount = totalStakedAmount.add(amount);
totalVcaRegisteredShares = totalVcaRegisteredShares.add(shares);
uint256 oldTotalSharesOf = totalSharesOf[staker];
totalSharesOf[staker] = totalSharesOf[staker].add(shares);
rebalance(staker, oldTotalSharesOf);
sessionDataOf[staker][sessionId] = Session({
amount: amount,
start: start,
end: end,
shares: shares,
firstPayout: firstPayout,
lastPayout: firstPayout + stakingDays,
withdrawn: false,
payout: 0
});
sessionsOf[staker].push(sessionId);
// add shares to bpd pool
addBPDShares(shares, start, end);
emit Stake(staker, sessionId, amount, start, end, shares);
}
internal Staking.withdrawDivTokenInternal keyboard_arrow_up
Source Code
function withdrawDivTokenInternal(address tokenAddress, uint256 _totalSharesOf)
internal
{
uint256 tokenInterestEarned = getTokenInterestEarnedInternal(
msg.sender,
tokenAddress,
_totalSharesOf
);
// after dividents are paid we need to set the deductBalance of that token to current token price * total shares of the account
deductBalances[msg.sender][tokenAddress] = totalSharesOf[msg.sender].mul(
tokenPricePerShare[tokenAddress]
);
/** 0xFF... is our ethereum placeholder address */
if (tokenAddress != address(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF)) {
IERC20Upgradeable(tokenAddress).transfer(msg.sender, tokenInterestEarned);
} else {
msg.sender.transfer(tokenInterestEarned);
}
emit WithdrawLiquidDiv(msg.sender, tokenAddress, tokenInterestEarned);
}
internal Staking.getTokenInterestEarnedInternal keyboard_arrow_up
Parameters help
Source Code
function getTokenInterestEarnedInternal(
address accountAddress,
address tokenAddress,
uint256 _totalSharesOf
) internal view returns (uint256) {
return
_totalSharesOf
.mul(tokenPricePerShare[tokenAddress])
.sub(deductBalances[accountAddress][tokenAddress])
.div(10**36); //we divide since we multiplied the price by 10**36 for precision
}
internal Staking.rebalance keyboard_arrow_up
Source Code
function rebalance(address staker, uint256 oldTotalSharesOf) internal {
for (uint8 i = 0; i < divTokens.length(); i++) {
uint256 tokenInterestEarned = oldTotalSharesOf
.mul(tokenPricePerShare[divTokens.at(i)])
.sub(deductBalances[staker][divTokens.at(i)]);
if (
totalSharesOf[staker].mul(tokenPricePerShare[divTokens.at(i)]) <
tokenInterestEarned
) {
withdrawDivTokenInternal(divTokens.at(i), oldTotalSharesOf);
} else {
deductBalances[staker][divTokens.at(i)] = totalSharesOf[staker]
.mul(tokenPricePerShare[divTokens.at(i)])
.sub(tokenInterestEarned);
}
}
}
internal Staking.setTotalSharesOfAccountInternal keyboard_arrow_up
Modifiers help
pausable checks for the following:
Requirements help
Source Code
function setTotalSharesOfAccountInternal(address account) internal pausable {
require(
isVcaRegistered[account] == false || hasRole(MIGRATOR_ROLE, msg.sender),
"STAKING: Account already registered."
);
uint256 totalShares;
//pull the layer 2 staking sessions for the account
uint256[] storage sessionsOfAccount = sessionsOf[account];
for (uint256 i = 0; i < sessionsOfAccount.length; i++) {
if (sessionDataOf[account][sessionsOfAccount[i]].withdrawn)
//make sure the stake is active; not withdrawn
continue;
totalShares = totalShares.add( //sum total shares
sessionDataOf[account][sessionsOfAccount[i]].shares
);
}
//pull stakes from layer 1
uint256[] memory v1SessionsOfAccount = stakingV1.sessionsOf_(account);
for (uint256 i = 0; i < v1SessionsOfAccount.length; i++) {
if (sessionDataOf[account][v1SessionsOfAccount[i]].shares != 0)
//make sure the stake was not withdran.
continue;
if (v1SessionsOfAccount[i] > lastSessionIdV1) continue; //make sure we only take layer 1 stakes in consideration
(
uint256 amount,
uint256 start,
uint256 end,
uint256 shares,
uint256 firstPayout
) = stakingV1.sessionDataOf(account, v1SessionsOfAccount[i]);
(amount);
(start);
(end);
(firstPayout);
if (shares == 0) continue;
totalShares = totalShares.add(shares); //calclate total shares
}
isVcaRegistered[account] = true; //confirm the registration was completed
if (totalShares != 0) {
totalSharesOf[account] = totalShares;
totalVcaRegisteredShares = totalVcaRegisteredShares.add(totalShares); //update the global total number of VCA registered shares
//init deductBalances with the present values
for (uint256 i = 0; i < divTokens.length(); i++) {
deductBalances[account][divTokens.at(i)] = totalShares.mul(
tokenPricePerShare[divTokens.at(i)]
);
}
}
emit AccountRegistered(account, totalShares);
}
internal Staking.updateShareRate keyboard_arrow_up
Source Code
function updateShareRate(uint256 _payout) internal {
uint256 currentTokenTotalSupply = IERC20Upgradeable(addresses.mainToken)
.totalSupply();
uint256 growthFactor = _payout.mul(1e18).div(
currentTokenTotalSupply + totalStakedAmount + 1 //we calculate the total AXN supply as circulating + staked
);
if (shareRateScalingFactor == 0) {
//use a shareRateScalingFactor which can be set in order to tune the speed of shareRate increase
shareRateScalingFactor = 1;
}
shareRate = shareRate
.mul(1e18 + shareRateScalingFactor.mul(growthFactor)) //1e18 used for precision.
.div(1e18);
}
internal Staking.maxShareUpgrade keyboard_arrow_up
Parameters help
Requirements help
Source Code
function maxShareUpgrade(
uint256 firstPayout,
uint256 lastPayout,
uint256 shares,
uint256 amount
)
internal
view
returns (
uint256,
uint256,
uint256,
uint256
)
{
require(
maxShareEventActive == true,
"STAKING: Max Share event is not active"
);
require(
lastPayout - firstPayout <= maxShareMaxDays,
"STAKING: Max Share Upgrade - Stake must be less then max share max days"
);
uint256 stakingInterest = calculateStakingInterest(
firstPayout,
lastPayout,
shares
);
uint256 newStart = now;
uint256 newEnd = newStart + (stepTimestamp * 5555);
uint256 newAmount = stakingInterest + amount;
uint256 newShares = _getStakersSharesAmount(newAmount, newStart, newEnd);
require(
newShares > shares,
"STAKING: New shares are not greater then previous shares"
);
return (newStart, newEnd, newAmount, newShares);
}
internal Staking.maxShareInternal keyboard_arrow_up
Parameters help
Source Code
function maxShareInternal(
uint256 sessionId,
uint256 oldShares,
uint256 newShares,
uint256 oldAmount,
uint256 newAmount,
uint256 newStart,
uint256 newEnd
) internal {
if (now >= nextPayoutCall) makePayout();
if (isVcaRegistered[msg.sender] == false)
setTotalSharesOfAccountInternal(msg.sender);
sharesTotalSupply = sharesTotalSupply.add(newShares - oldShares);
totalStakedAmount = totalStakedAmount.add(newAmount - oldAmount);
totalVcaRegisteredShares = totalVcaRegisteredShares.add(
newShares - oldShares
);
uint256 oldTotalSharesOf = totalSharesOf[msg.sender];
totalSharesOf[msg.sender] = totalSharesOf[msg.sender].add(
newShares - oldShares
);
rebalance(msg.sender, oldTotalSharesOf);
emit MaxShareUpgrade(
msg.sender,
sessionId,
oldAmount,
newAmount,
oldShares,
newShares,
newStart,
newEnd
);
}
internal Staking.findBPDs keyboard_arrow_up
Source Code
function findBPDs(uint256 starttime, uint256 endtime)
internal
view
returns (uint16[2] memory)
{
uint16[2] memory bpdInterval;
uint256 denom = stepTimestamp.mul(350);
bpdInterval[0] = uint16(
MathUpgradeable.min(5, starttime.sub(startContract).div(denom))
); // (starttime - t0) // 350
uint256 bpdEnd = uint256(bpdInterval[0]) + endtime.sub(starttime).div(denom);
bpdInterval[1] = uint16(MathUpgradeable.min(bpdEnd, 5)); // bpd_first + nx350
return bpdInterval;
}
internal Staking.addBPDMaxShares keyboard_arrow_up
Parameters help
Source Code
function addBPDMaxShares(
uint256 oldShares,
uint256 oldStart,
uint256 oldEnd,
uint256 newShares,
uint256 newStart,
uint256 newEnd
) internal {
uint16[2] memory oldBpdInterval = findBPDs(oldStart, oldEnd);
uint16[2] memory newBpdInterval = findBPDs(newStart, newEnd);
for (uint16 i = oldBpdInterval[0]; i < newBpdInterval[1]; i++) {
uint256 shares = newShares;
if (oldBpdInterval[1] > i) {
shares = shares.sub(oldShares);
}
bpd128.shares[i] += uint128(shares); // we only do integer shares, no decimals
}
}
internal Staking.addBPDShares keyboard_arrow_up
Source Code
function addBPDShares(
uint256 shares,
uint256 starttime,
uint256 endtime
) internal {
uint16[2] memory bpdInterval = findBPDs(starttime, endtime);
for (uint16 i = bpdInterval[0]; i < bpdInterval[1]; i++) {
bpd128.shares[i] += uint128(shares); // we only do integer shares, no decimals
}
}
internal Staking.calcBPDOnWithdraw keyboard_arrow_up
Source Code
function calcBPDOnWithdraw(uint256 shares, uint16[2] memory bpdInterval)
internal
view
returns (uint256)
{
uint256 bpdAmount;
uint256 shares1e18 = shares.mul(1e18);
for (uint16 i = bpdInterval[0]; i < bpdInterval[1]; i++) {
bpdAmount += shares1e18.div(bpd128.shares[i]).mul(bpd128.pool[i]);
}
return bpdAmount.div(1e18);
}
internal Initializable._isConstructor keyboard_arrow_up
internal AccessControlUpgradeable.__AccessControl_init keyboard_arrow_up
Parameters help
This function has no parameters.
Modifiers help
initializer checks for the following:
One or more of the following:
-_initialized must not be true - ORnull - OR_initializing must be true
Source Code
function __AccessControl_init() internal initializer {
__Context_init_unchained();
__AccessControl_init_unchained();
}
internal AccessControlUpgradeable.__AccessControl_init_unchained keyboard_arrow_up
Parameters help
This function has no parameters.
Modifiers help
initializer checks for the following:
One or more of the following:
-_initialized must not be true - ORnull - OR_initializing must be true
Source Code
function __AccessControl_init_unchained() internal initializer {}
internal AccessControlUpgradeable._setupRole keyboard_arrow_up
internal AccessControlUpgradeable._setRoleAdmin keyboard_arrow_up
Source Code
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);
_roles[role].adminRole = adminRole;
}
internal AccessControlUpgradeable._grantRole keyboard_arrow_up
internal AccessControlUpgradeable._revokeRole keyboard_arrow_up
internal Initializable._isConstructor keyboard_arrow_up
internal ContextUpgradeable.__Context_init keyboard_arrow_up
Parameters help
This function has no parameters.
Modifiers help
initializer checks for the following:
One or more of the following:
-_initialized must not be true - ORnull - OR_initializing must be true
Source Code
function __Context_init() internal initializer {
__Context_init_unchained();
}
internal ContextUpgradeable.__Context_init_unchained keyboard_arrow_up
Parameters help
This function has no parameters.
Modifiers help
initializer checks for the following:
One or more of the following:
-_initialized must not be true - ORnull - OR_initializing must be true
Source Code
function __Context_init_unchained() internal initializer {}
internal ContextUpgradeable._msgSender keyboard_arrow_up
internal ContextUpgradeable._msgData keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}