About
Stats
Public Functions
47
Event Types
7
Code Size
101,102 bytes
Library Use
Uses SafeMath for uint256.
Uses Strings for uint256.
Uses AddressStrings for address.
Events (7) keyboard_arrow_up
Constants (12) keyboard_arrow_up
State Variables (51) keyboard_arrow_up
Functions
owner keyboard_arrow_up
renounceOwnership keyboard_arrow_up
transferOwnership keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
Source Code
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
supportsInterface keyboard_arrow_up
balanceOf keyboard_arrow_up
Source Code
function balanceOf(address owner) public view override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _holderTokens[owner].length();
}
ownerOf keyboard_arrow_up
name keyboard_arrow_up
symbol keyboard_arrow_up
tokenURI keyboard_arrow_up
Requirements help
null
Source Code
function tokenURI(uint256 tokenId)
public
view
override
returns (string memory)
{
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
//this line altered from
//string memory _tokenURI = _tokenURIs[tokenId];
//use of gas to manipulate strings can be avoided by putting them together at time of retrieval rather than in the token creation transaction.
string memory _tokenURI = putTogetherMetadataString(tokenId);
// If there is no base URI, return the token URI.
if (bytes(baseURI()).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(baseURI(), _tokenURI));
}
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
return string(abi.encodePacked(baseURI(), tokenId.toString()));
}
baseURI keyboard_arrow_up
tokenOfOwnerByIndex keyboard_arrow_up
totalSupply keyboard_arrow_up
tokenByIndex keyboard_arrow_up
approve keyboard_arrow_up
Requirements help
Source Code
function approve(address to, uint256 tokenId) public virtual override {
address owner = ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
getApproved keyboard_arrow_up
Requirements help
null
Source Code
function getApproved(uint256 tokenId) public view override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
setApprovalForAll keyboard_arrow_up
Requirements help
Source Code
function setApprovalForAll(address operator, bool approved)
public
virtual
override
{
require(operator != _msgSender(), "ERC721: approve to caller");
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
isApprovedForAll keyboard_arrow_up
transferFrom keyboard_arrow_up
Requirements help
Source Code
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
//solhint-disable-next-line max-line-length
require(
_isApprovedOrOwner(_msgSender(), tokenId),
"ERC721: transfer caller is not owner nor approved"
);
_transfer(from, to, tokenId);
}
safeTransferFrom keyboard_arrow_up
Requirements help
Source Code
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
safeTransferFrom keyboard_arrow_up
Requirements help
Source Code
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
require(
_isApprovedOrOwner(_msgSender(), tokenId),
"ERC721: transfer caller is not owner nor approved"
);
_safeTransfer(from, to, tokenId, _data);
}
setBaseURI keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
Source Code
function setBaseURI(string calldata baseURI_) external onlyOwner {
_setBaseURI(baseURI_);
}
setLiquidityTokenAccepted keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
Source Code
function setLiquidityTokenAccepted(address token, bool accepted)
external
onlyOwner
{
tokenAccepted[token] = accepted;
}
setLiquidityTokenAcceptedMulti keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
Source Code
function setLiquidityTokenAcceptedMulti(
address[] calldata tokens,
bool accepted
) external onlyOwner {
for (uint256 i = 0; i < tokens.length; i++) {
tokenAccepted[tokens[i]] = accepted;
}
}
setSyncMinimum keyboard_arrow_up
setPriceOracle keyboard_arrow_up
toggleLuckyBonus keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
Source Code
function toggleLuckyBonus(bool enabled) external onlyOwner {
luckyEnabled = enabled;
}
recordSyncAndTokens keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
Source Code
function recordSyncAndTokens(address[] calldata tokens) external onlyOwner {
recordSyncSupply();
for (uint256 i = 0; i < tokens.length; i++) {
recordTokenSupply(tokens[i]);
}
}
cashOutDivs keyboard_arrow_up
Requirements help
Source Code
function cashOutDivs(uint256 tokenId) external {
require(msg.sender == ownerOf(tokenId), "only token owner can call this");
require(gradualDivsById[tokenId], "must be in quarterly dividends mode");
//record current Sync supply and liquidity token supply for the day if needed
recordSyncSupply();
recordTokenSupply(lAddrById[tokenId]);
//reward user with appropriate amount. If none is due it will provide an amount of 0 tokens.
uint256 divs = dividendsOf(tokenId);
syncToken._mint(msg.sender, divs);
//register the timestamp of this transaction so future div payouts can be accurately calculated
lastDivsCashoutById[tokenId] = block.timestamp;
//update read variables
totalDivsCashoutById[tokenId] = totalDivsCashoutById[tokenId].add(divs);
emit DivsPaid(lAddrById[tokenId], divs, tokenId);
}
matureCBOND keyboard_arrow_up
Requirements help
Source Code
function matureCBOND(uint256 tokenId) public {
require(msg.sender == ownerOf(tokenId), "only token owner can call this");
require(
block.timestamp > termLengthById[tokenId].add(timestampById[tokenId]),
"cbond term not yet completed"
);
//record current Sync supply and liquidity token supply for the day if needed
recordSyncSupply();
recordTokenSupply(lAddrById[tokenId]);
//amount of sync provided to user is initially deposited amount plus interest
uint256 syncRetrieved = syncRewardedOnMaturity[tokenId];
//provide user with their Sync tokens and their initially deposited liquidity tokens
uint256 beforeMint = syncToken.balanceOf(msg.sender);
syncToken._mint(msg.sender, syncRetrieved);
require(
IERC20(lAddrById[tokenId]).transfer(msg.sender, lTokenAmountById[tokenId]),
"transfer must succeed"
);
//update read only counter
totalCBONDSCashedout = totalCBONDSCashedout.add(1);
emit Matured(
lAddrById[tokenId],
syncRetrieved,
lTokenAmountById[tokenId],
tokenId
);
//burn the nft
_burn(tokenId);
}
createCBOND keyboard_arrow_up
Parameters help
Requirements help
null
Source Code
function createCBOND(
address liquidityToken,
uint256 amount,
uint256 syncMaximum,
uint256 secondsInTerm,
bool gradualDivs
) external returns (uint256) {
return
_createCBOND(
liquidityToken,
amount,
syncMaximum,
secondsInTerm,
gradualDivs,
msg.sender
);
}
putTogetherMetadataString keyboard_arrow_up
Source Code
function putTogetherMetadataString(uint256 tokenId)
public
view
returns (string memory)
{
//TODO: add the rest of the variables, separate with appropriate url variable separators for ease of use
string memory isDivs = gradualDivsById[tokenId] ? "true" : "false";
return
string(
abi.encodePacked(
"/?tokenId=",
tokenId.toString(),
"&lAddr=",
lAddrById[tokenId].toString(),
"&syncPrice=",
syncPriceById[tokenId].toString(),
"&syncAmount=",
syncAmountById[tokenId].toString(),
"&mPayout=",
syncRewardedOnMaturity[tokenId].toString(),
"&lPrice=",
lTokenPriceById[tokenId].toString(),
"&lAmount=",
lTokenAmountById[tokenId].toString(),
"&startTime=",
timestampById[tokenId].toString(),
"&isDivs=",
isDivs,
"&termLength=",
termLengthById[tokenId].toString(),
"&divsNow=",
dividendsOf(tokenId).toString()
)
);
}
getTime keyboard_arrow_up
dividendsOf keyboard_arrow_up
Requirements help
Source Code
function dividendsOf(uint256 tokenId) public view returns (uint256) {
//determine the number of periods worth of divs the token owner is owed, by subtracting the current period by the period when divs were last withdrawn.
require(lastDivsCashoutById[tokenId] >= timestampById[tokenId], "dof1");
uint256 lastCashoutInPeriod = lastDivsCashoutById[tokenId]
.sub(timestampById[tokenId])
.div(QUARTER_LENGTH); //0 - first quarter, 1 - second, etc. This variable also represents the number of quarters previously cashed out
require(block.timestamp >= timestampById[tokenId], "dof2");
uint256 currentCashoutInPeriod = block
.timestamp
.sub(timestampById[tokenId])
.div(QUARTER_LENGTH);
require(currentCashoutInPeriod >= lastCashoutInPeriod, "dof3");
uint256 periodsToCashout = currentCashoutInPeriod.sub(lastCashoutInPeriod);
//only accrue divs before the maturation date. The final div payment will be paid as part of the matureCBOND transaction, so set the maximum number of periods to cash out be one less than the ultimate total.
if (currentCashoutInPeriod >= termLengthById[tokenId].div(90 days)) {
//possible for lastCashout period to be greater due to being able to cash out after CBOND has ended (which records lastCashout as being after that date, despite only paying out for earlier periods). In this case, set periodsToCashout to 0 and ultimately return 0, there are no divs left.
if (lastCashoutInPeriod > termLengthById[tokenId].div(90 days).sub(1)) {
periodsToCashout = 0;
} else {
periodsToCashout = termLengthById[tokenId].div(90 days).sub(1).sub(
lastCashoutInPeriod
);
}
}
//multiply the number of periods to pay out with the amount of divs owed for one period. Note: if this is a Quarterly Cbond, syncInterestById will have been recorded as the interest per quarter, rather than the total interest for the Cbond, as with a normal Cbond.
uint256 quarterlyDividend = syncInterestById[tokenId];
return
periodsToCashout.mul(syncAmountById[tokenId]).mul(quarterlyDividend).div(
PERCENTAGE_PRECISION
);
}
getSyncRequiredForCreation keyboard_arrow_up
Source Code
function getSyncRequiredForCreation(IERC20 liquidityToken, uint256 amount)
external
view
returns (uint256)
{
return
priceChecker.liquidityValues(address(liquidityToken)).mul(amount).div(
priceChecker.syncValue()
);
}
getCbondTotalReturn keyboard_arrow_up
Parameters help
Source Code
function getCbondTotalReturn(
uint256 tokenId,
uint256 syncAmount,
address liqAddr,
uint256 duration,
bool isDivs
) public view returns (uint256 interestRate, uint256 totalReturn) {
// This is an integer math translation of P*(1+I) where P is principle I is interest rate. The new, equivalent formula is P*(c+I*c)/c where c is a constant of amount PERCENTAGE_PRECISION.
interestRate = getCbondInterestRateNow(
liqAddr,
duration,
getLuckyExtra(tokenId),
isDivs
);
totalReturn = syncAmount.mul(PERCENTAGE_PRECISION.add(interestRate)).div(
PERCENTAGE_PRECISION
);
}
getCbondInterestRateNow keyboard_arrow_up
Parameters help
Source Code
function getCbondInterestRateNow(
address liqAddr,
uint256 duration,
uint256 luckyExtra,
bool quarterly
) public view returns (uint256) {
return
getCbondInterestRate(
duration,
liqTokenTotalsByDay[liqAddr][lastDayTokenSupplyUpdated[liqAddr]],
liqTokenTotalsByDay[liqAddr][getDay(block.timestamp)],
syncSupplyByDay[lastDaySyncSupplyUpdated],
syncSupplyByDay[getDay(block.timestamp)],
interestRateByDay[lastDaySyncSupplyUpdated],
luckyExtra,
quarterly
);
}
getCbondInterestRate keyboard_arrow_up
Parameters help
Source Code
function getCbondInterestRate(
uint256 duration,
uint256 liqTotalLast,
uint256 liqTotalCurrent,
uint256 syncTotalLast,
uint256 syncTotalCurrent,
uint256 lastBaseInterestRate,
uint256 luckyExtra,
bool quarterly
) public view returns (uint256) {
uint256 liquidityPairIncentiveRate = getLiquidityPairIncentiveRate(
liqTotalCurrent,
liqTotalLast
);
uint256 baseInterestRate = getBaseInterestRate(
lastBaseInterestRate,
syncTotalCurrent,
syncTotalLast
);
if (!quarterly) {
return
getDurationRate(
duration,
baseInterestRate.add(liquidityPairIncentiveRate).add(luckyExtra)
);
} else {
uint256 numYears = duration.div(YEAR_LENGTH);
require(numYears > 0, "invalid duration"); //Quarterly Cbonds must have a duration 1 year or longer.
uint256 numQuarters = duration.div(QUARTER_LENGTH);
uint256 termModifier = RISK_FACTOR.mul(numYears.mul(4).sub(1));
//Interest rate is the sum of base interest rate, liquidity incentive rate, and risk/term based modifier. Because this is the Quarterly Cbond rate, we also divide by the number of quarters in the Cbond, to set the recorded rate to the amount withdrawable per quarter.
return
baseInterestRate.add(liquidityPairIncentiveRate).add(luckyExtra).add(
termModifier
);
}
}
getLuckyExtra keyboard_arrow_up
Source Code
function getLuckyExtra(uint256 tokenId) public view returns (uint256) {
if (luckyEnabled) {
if (tokenId.mod(100) == 77) {
return LUCKY_EXTRAS[0];
}
if (tokenId.mod(1000) == 777) {
return LUCKY_EXTRAS[1];
}
}
return 0;
}
getDurationRate keyboard_arrow_up
Requirements help
One or more of the following:
-
duration
must be equal to
TERM_DURATIONS for 4
- OR
duration
must be equal to
TERM_DURATIONS for 3
- OR
duration
must be equal to
TERM_DURATIONS for 2
- OR
duration
must be equal to
TERM_DURATIONS for 1
- OR
duration
must be equal to
TERM_DURATIONS for 0
Source Code
function getDurationRate(uint256 duration, uint256 baseInterestRate)
public
view
returns (uint256)
{
require(
duration == TERM_DURATIONS[0] ||
duration == TERM_DURATIONS[1] ||
duration == TERM_DURATIONS[2] ||
duration == TERM_DURATIONS[3] ||
duration == TERM_DURATIONS[4],
"Invalid CBOND term length provided"
);
if (duration == TERM_DURATIONS[0]) {
return baseInterestRate;
}
if (duration == TERM_DURATIONS[1]) {
uint256 preExponential = PERCENTAGE_PRECISION.add(baseInterestRate).add(
RISK_FACTOR
);
uint256 exponential = preExponential.mul(preExponential).div(
PERCENTAGE_PRECISION
);
return exponential.sub(PERCENTAGE_PRECISION);
}
if (duration == TERM_DURATIONS[2]) {
//1 year
uint256 preExponential = PERCENTAGE_PRECISION.add(baseInterestRate).add(
RISK_FACTOR.mul(3)
);
uint256 exponential = preExponential.mul(preExponential).div(
PERCENTAGE_PRECISION
);
for (uint8 i = 0; i < 2; i++) {
exponential = exponential.mul(preExponential).div(PERCENTAGE_PRECISION);
}
return exponential.sub(PERCENTAGE_PRECISION);
}
if (duration == TERM_DURATIONS[3]) {
//2 years
uint256 preExponential = PERCENTAGE_PRECISION.add(baseInterestRate).add(
RISK_FACTOR.mul(7)
);
uint256 exponential = preExponential.mul(preExponential).div(
PERCENTAGE_PRECISION
);
for (uint8 i = 0; i < 6; i++) {
exponential = exponential.mul(preExponential).div(PERCENTAGE_PRECISION);
}
return exponential.sub(PERCENTAGE_PRECISION);
}
if (duration == TERM_DURATIONS[4]) {
//3 years
uint256 preExponential = PERCENTAGE_PRECISION.add(baseInterestRate).add(
RISK_FACTOR.mul(11)
);
uint256 exponential = preExponential.mul(preExponential).div(
PERCENTAGE_PRECISION
);
for (uint8 i = 0; i < 10; i++) {
exponential = exponential.mul(preExponential).div(PERCENTAGE_PRECISION);
}
return exponential.sub(PERCENTAGE_PRECISION);
}
}
getLiquidityPairIncentiveRate keyboard_arrow_up
Source Code
function getLiquidityPairIncentiveRate(
uint256 totalToday,
uint256 totalYesterday
) public view returns (uint256) {
//instead of reverting due to division by zero, if tokens in this contract go to zero give the max bonus
if (totalToday == 0) {
return INCENTIVE_MAX_PERCENT;
}
return
Math.min(
INCENTIVE_MAX_PERCENT,
INCENTIVE_MAX_PERCENT.mul(totalYesterday).div(totalToday)
);
}
getBaseInterestRate keyboard_arrow_up
Parameters help
Source Code
function getBaseInterestRate(
uint256 lastdayInterestRate,
uint256 syncSupplyToday,
uint256 syncSupplyLast
) public pure returns (uint256) {
return
Math.min(
MAXIMUM_BASE_INTEREST_RATE,
Math.max(
MINIMUM_BASE_INTEREST_RATE,
lastdayInterestRate.mul(syncSupplyToday).div(syncSupplyLast)
)
);
}
getCbondInterestRateIfUpdated keyboard_arrow_up
Parameters help
Source Code
function getCbondInterestRateIfUpdated(
address liqAddr,
uint256 duration,
uint256 luckyExtra,
bool quarterly
) public view returns (uint256) {
(
uint256 lastSupply,
uint256 currentSupply,
uint256 lastTSupply,
uint256 currentTSupply,
uint256 lastInterestRate
) = getSuppliesIfUpdated(liqAddr);
return
getCbondInterestRate(
duration,
lastTSupply,
currentTSupply,
lastSupply,
currentSupply,
lastInterestRate,
luckyExtra,
quarterly
);
}
getSuppliesNow keyboard_arrow_up
Source Code
function getSuppliesNow(address tokenAddr)
public
view
returns (
uint256 lastSupply,
uint256 currentSupply,
uint256 lastTSupply,
uint256 currentTSupply,
uint256 lastInterestRate
)
{
currentSupply = syncSupplyByDay[currentDaySyncSupplyUpdated];
lastSupply = syncSupplyByDay[lastDaySyncSupplyUpdated];
lastInterestRate = interestRateByDay[lastDaySyncSupplyUpdated];
currentTSupply = liqTokenTotalsByDay[tokenAddr][
currentDayTokenSupplyUpdated[tokenAddr]
];
lastTSupply = liqTokenTotalsByDay[tokenAddr][
lastDayTokenSupplyUpdated[tokenAddr]
];
}
getSuppliesIfUpdated keyboard_arrow_up
Source Code
function getSuppliesIfUpdated(address tokenAddr)
public
view
returns (
uint256 lastSupply,
uint256 currentSupply,
uint256 lastTSupply,
uint256 currentTSupply,
uint256 lastInterestRate
)
{
uint256 day = getDay(block.timestamp);
if (liqTokenTotalsByDay[tokenAddr][getDay(block.timestamp)] == 0) {
currentTSupply = IERC20(tokenAddr).balanceOf(address(this));
lastTSupply = liqTokenTotalsByDay[tokenAddr][
currentDayTokenSupplyUpdated[tokenAddr]
];
} else {
currentTSupply = liqTokenTotalsByDay[tokenAddr][
currentDayTokenSupplyUpdated[tokenAddr]
];
lastTSupply = liqTokenTotalsByDay[tokenAddr][
lastDayTokenSupplyUpdated[tokenAddr]
];
}
if (syncSupplyByDay[day] == 0) {
currentSupply = syncToken.totalSupply();
lastSupply = syncSupplyByDay[currentDaySyncSupplyUpdated];
//TODO: interest rate
lastInterestRate = interestRateByDay[currentDaySyncSupplyUpdated];
} else {
currentSupply = syncSupplyByDay[currentDaySyncSupplyUpdated];
lastSupply = syncSupplyByDay[lastDaySyncSupplyUpdated];
lastInterestRate = interestRateByDay[lastDaySyncSupplyUpdated];
}
}
recordSyncSupply keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function recordSyncSupply() public {
if (syncSupplyByDay[getDay(block.timestamp)] == 0) {
uint256 day = getDay(block.timestamp);
syncSupplyByDay[day] = syncToken.totalSupply();
lastDaySyncSupplyUpdated = currentDaySyncSupplyUpdated;
currentDaySyncSupplyUpdated = day;
//interest rate
interestRateByDay[day] = getBaseInterestRate(
interestRateByDay[lastDaySyncSupplyUpdated],
syncSupplyByDay[day],
syncSupplyByDay[lastDaySyncSupplyUpdated]
);
}
}
getDay keyboard_arrow_up
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 CBOND._createCBOND keyboard_arrow_up
Parameters help
Requirements help
null
Source Code
function _createCBOND(
address liquidityToken,
uint256 amount,
uint256 syncMaximum,
uint256 secondsInTerm,
bool gradualDivs,
address sender
) private returns (uint256) {
require(
tokenAccepted[liquidityToken],
"liquidity token must be on the list of approved tokens"
);
//record current Sync supply and liquidity token supply for the day if needed
recordSyncSupply();
recordTokenSupply(liquidityToken);
//determine amount of Sync required, given the amount of liquidity tokens specified, and transfer that amount from the user
uint256 liquidityValue = priceChecker.liquidityValues(liquidityToken);
uint256 syncValue = priceChecker.syncValue();
//Since syncRequired is the exact amount of Sync that will be transferred from the user, integer division truncations propagating to other values derived from this one is the correct behavior.
uint256 syncRequired = liquidityValue.mul(amount).div(syncValue);
require(
syncRequired >= syncMinimum,
"input tokens too few, sync transferred must be above the minimum"
);
require(
syncRequired <= syncMaximum,
"price changed too much since transaction submitted"
);
require(syncRequired <= MAX_SYNC_GLOBAL, "CBOND amount too large");
syncToken.transferFrom(sender, address(this), syncRequired);
require(
IERC20(liquidityToken).transferFrom(sender, address(this), amount),
"transfer must succeed"
);
//burn sync tokens provided
syncToken.burn(syncRequired);
//get the token id of the new NFT
uint256 tokenId = _getNextTokenId();
//set all nft variables
lAddrById[tokenId] = liquidityToken;
syncPriceById[tokenId] = syncValue;
syncAmountById[tokenId] = syncRequired;
lTokenPriceById[tokenId] = liquidityValue;
lTokenAmountById[tokenId] = amount;
timestampById[tokenId] = block.timestamp;
lastDivsCashoutById[tokenId] = block.timestamp;
gradualDivsById[tokenId] = gradualDivs;
termLengthById[tokenId] = secondsInTerm;
//set the interest rate and final maturity withdraw amount
setInterestRate(
tokenId,
syncRequired,
liquidityToken,
secondsInTerm,
gradualDivs
);
//update global counters
cbondsMaturingByDay[
getDay(block.timestamp.add(secondsInTerm))
] = cbondsMaturingByDay[getDay(block.timestamp.add(secondsInTerm))].add(1);
cbondsHeldByUser[sender][cbondsHeldByUserCursor[sender]] = tokenId;
cbondsHeldByUserCursor[sender] = cbondsHeldByUserCursor[sender].add(1);
totalCBONDS = totalCBONDS.add(1);
totalSYNCLocked = totalSYNCLocked.add(syncRequired);
totalLiquidityLockedByPair[liquidityToken] = totalLiquidityLockedByPair[
liquidityToken
]
.add(amount);
//create NFT
_safeMint(sender, tokenId);
_incrementTokenId();
//submit event
emit Created(
liquidityToken,
syncRequired,
amount,
syncValue,
liquidityValue,
tokenId
);
return tokenId;
}
internal CBOND._incrementTokenId keyboard_arrow_up
internal CBOND._getNextTokenId keyboard_arrow_up
internal CBOND.setInterestRate keyboard_arrow_up
Parameters help
Source Code
function setInterestRate(
uint256 tokenId,
uint256 syncRequired,
address liquidityToken,
uint256 secondsInTerm,
bool gradualDivs
) private {
(
uint256 lastSupply,
uint256 currentSupply,
uint256 lastTSupply,
uint256 currentTSupply,
uint256 lastInterestRate
) = getSuppliesNow(liquidityToken);
(uint256 interestRate, uint256 totalReturn) = getCbondTotalReturn(
tokenId,
syncRequired,
liquidityToken,
secondsInTerm,
gradualDivs
);
syncRewardedOnMaturity[tokenId] = totalReturn;
syncInterestById[tokenId] = interestRate;
if (gradualDivs) {
require(
secondsInTerm >= TERM_DURATIONS[2],
"dividend bearing CBONDs must be at least 1 year duration"
);
totalQuarterlyCBONDS = totalQuarterlyCBONDS.add(1);
}
}
internal CBOND.recordTokenSupply keyboard_arrow_up
Source Code
function recordTokenSupply(address tokenAddr) private {
if (liqTokenTotalsByDay[tokenAddr][getDay(block.timestamp)] == 0) {
uint256 day = getDay(block.timestamp);
liqTokenTotalsByDay[tokenAddr][day] = IERC20(tokenAddr).balanceOf(
address(this)
);
lastDayTokenSupplyUpdated[tokenAddr] = currentDayTokenSupplyUpdated[
tokenAddr
];
currentDayTokenSupplyUpdated[tokenAddr] = day;
}
}
internal ERC721._safeTransfer keyboard_arrow_up
Requirements help
Source Code
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_transfer(from, to, tokenId);
require(
_checkOnERC721Received(from, to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
internal ERC721._exists keyboard_arrow_up
internal ERC721._isApprovedOrOwner keyboard_arrow_up
Requirements help
null
Source Code
function _isApprovedOrOwner(address spender, uint256 tokenId)
internal
view
returns (bool)
{
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ownerOf(tokenId);
return (spender == owner ||
getApproved(tokenId) == spender ||
isApprovedForAll(owner, spender));
}
internal ERC721._safeMint keyboard_arrow_up
Requirements help
null
Source Code
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
internal ERC721._safeMint keyboard_arrow_up
Requirements help
null
Source Code
function _safeMint(
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
internal ERC721._mint keyboard_arrow_up
Requirements help
Source Code
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_holderTokens[to].add(tokenId);
_tokenOwners.set(tokenId, to);
emit Transfer(address(0), to, tokenId);
}
internal ERC721._burn keyboard_arrow_up
Source Code
function _burn(uint256 tokenId) internal virtual {
address owner = ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
// Clear approvals
_approve(address(0), tokenId);
// Clear metadata (if any)
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
_holderTokens[owner].remove(tokenId);
_tokenOwners.remove(tokenId);
emit Transfer(owner, address(0), tokenId);
}
internal ERC721._transfer keyboard_arrow_up
Requirements help
Source Code
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(
ownerOf(tokenId) == from,
"ERC721: transfer of token that is not own"
);
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
// Clear approvals from the previous owner
_approve(address(0), tokenId);
_holderTokens[from].remove(tokenId);
_holderTokens[to].add(tokenId);
_tokenOwners.set(tokenId, to);
emit Transfer(from, to, tokenId);
}
internal ERC721._setTokenURI keyboard_arrow_up
Requirements help
null
Source Code
function _setTokenURI(uint256 tokenId, string memory _tokenURI)
internal
virtual
{
require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
internal ERC721._setBaseURI keyboard_arrow_up
internal ERC721._checkOnERC721Received keyboard_arrow_up
Source Code
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
if (!to.isContract()) {
return true;
}
bytes memory returndata = to.functionCall(
abi.encodeWithSelector(
IERC721Receiver(to).onERC721Received.selector,
_msgSender(),
from,
tokenId,
_data
),
"ERC721: transfer to non ERC721Receiver implementer"
);
bytes4 retval = abi.decode(returndata, (bytes4));
return (retval == _ERC721_RECEIVED);
}
internal ERC721._approve keyboard_arrow_up
internal ERC721._beforeTokenTransfer keyboard_arrow_up
internal Context._msgSender keyboard_arrow_up
internal Context._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;
}
internal ERC165.constructor keyboard_arrow_up
internal ERC165._registerInterface keyboard_arrow_up
Requirements help
Source Code
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
internal Ownable.constructor keyboard_arrow_up
internal Context._msgSender keyboard_arrow_up
internal Context._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;
}