SMART Token
SmartToken
Inherits: Initializable, UUPSUpgradeable, OwnableUpgradeable, ERC20Upgradeable, ERC20PermitUpgradeable, BaseContract, IERC4626Upgradeable, ReentrancyGuardUpgradeable, FlashloanSpecifics
This is a rebalancing token, part of Risk Protocol's system The same contract is used by both RiskON and RiskOFF Whenever a user deposit a unit of underlying in the Vault(TokenFactory), the user is expected to recieve a unit of both RiskON and RiskOFF. At every rebalance operation, the user RiskOn/OFF balances will be aligned with respect to the rebalance math.
State Variables
tokenFactory
The tokenFactory instance
TokenFactory private tokenFactory;
underlyingToken
The underlyingToken instance
IERC20Update private underlyingToken;
isX
bool private isX;
isNativeToken
bool private isNativeToken;
weth
IWETH private weth;
premiumDenominator
uint16 private constant premiumDenominator = 10000;
Functions
onlyTokenFactory
Ensures that the function is only callable by the TokenFactory contract. Calls the helper function _onlyTokenFactory
to check the caller.
modifier onlyTokenFactory();
onlyAssetOwner
Ensures that the function is only callable by the token owner/holder. Calls the helper function _onlyAssetOwner
to check the caller against the provided token owner/holder address.
modifier onlyAssetOwner(address assetOwner);
Parameters
assetOwner
address
The address of the token owner/holder.
validateDepositAmount
Validates the deposit amount to ensure it is not 0 or more than the receiver can get. Calls the helper function _validateDepositAmount
to check the deposit amount and receiver.
modifier validateDepositAmount(uint256 assets, address receiver);
Parameters
assets
uint256
The amount of token to deposit.
receiver
address
The address receiving the deposit.
insufficientUnderlying
Validates if the underlying locked is always >= than the total supply of riskON/OFF reverts if not
modifier insufficientUnderlying();
depositLimitHit
Validates if the user has hit the periodic deposit limit prevents the user from depositing more if hit
modifier depositLimitHit(uint256 amount);
Parameters
amount
uint256
The amount of token to deposit.
withdrawLimitHit
Validates if the user has hit the periodic withdraw limit prevents the user from withdrawing more if hit
modifier withdrawLimitHit(uint256 amount);
Parameters
amount
uint256
The amount of token to withdraw.
dailyFFUpdate
modifier dailyFFUpdate();
expiryDateCheck
modifier expiryDateCheck(uint256 expiryDate);
constructor
constructor();
initialize
Initializes(replacement for the constructor) the SmartToken contract with specified parameters.
This function sets up the initial state of the SmartToken contract. Callable only once. It initializes inherited contracts and sets the initial values for tokenFactory
and underlyingToken
.
function initialize(
string memory tokenName,
string memory tokenSymbol,
address factoryAddress,
address sanctionsContract_,
bool isX_,
address owner_
) public initializer;
Parameters
tokenName
string
The name of the token.
tokenSymbol
string
The symbol of the token.
factoryAddress
address
The address of the TokenFactory contract.
sanctionsContract_
address
The address of the SanctionsList contract.
isX_
bool
owner_
address
receive
receive() external payable;
drain
method to drain contracts of any ethers
This function can only be called by the contract owner.
function drain(address receiver) external onlyOwner;
Parameters
receiver
address
The address of the account that will receive the ethers.
_authorizeUpgrade
Authorizes an upgrade to a new contract implementation.
This function can only be called by the contract owner. It overrides the _authorizeUpgrade
function from the UUPSUpgradeable
contract to include the onlyOwner
modifier, ensuring only the owner can authorize upgrades.
function _authorizeUpgrade(address) internal override onlyOwner;
mintAsset
Mints the specified amount of tokens to the receiver.
This function can only be called by the TokenFactory contract.
function mintAsset(address receiver, uint256 amount) external onlyTokenFactory;
Parameters
receiver
address
The address of the account that will receive the minted tokens.
amount
uint256
The amount of tokens to mint.
burn
Burns the specified amount of tokens from the account.
This function can only be called by the TokenFactory contract.
function burn(address account, uint256 amount) external onlyTokenFactory;
Parameters
account
address
The address of the account from which tokens will be burned.
amount
uint256
The amount of tokens to burn.
transfer
Transfers the specified amount of tokens to the specified recipient.
Overrides the transfer
function from ERC20Upgradeable
and IERC20Upgradeable
contracts. If the sender or receiver has a pending rebalance, it is handled before the transfer. This function can only be called when transfers are not stopped, and neither the sender nor the recipient are on the sanctions list.
function transfer(address recipient, uint256 amount)
public
override(ERC20Upgradeable, IERC20Upgradeable)
stopTransfer
insufficientUnderlying
onlyNotSanctioned(recipient)
onlyNotSanctioned(_msgSender())
dailyFFUpdate
returns (bool);
Parameters
recipient
address
The address to which tokens will be transferred.
amount
uint256
The amount of tokens to transfer.
Returns
<none>
bool
Always return true unless reverted
smartTreasuryTransfer
function smartTreasuryTransfer(address treasuryAddress, uint256 amount) external onlyTokenFactory;
smartBalanceAdjust
function smartBalanceAdjust(address account, uint256 amount) external onlyTokenFactory;
balanceOf
Returns the balance of the specified account
Overrides the balanceOf
function from the inherited ERC20Upgradeable
and IERC20Upgradeable
contracts. If the account has a pending rebalance, the function calculates the calculated balance post rebalance using the 'calculateRollOverValue' method. Otherwise, it returns the erc20 balance using unScaledbalanceOf
method.
function balanceOf(address account) public view override(ERC20Upgradeable, IERC20Upgradeable) returns (uint256);
Parameters
account
address
The address of the account whose balance will be retrieved.
Returns
<none>
uint256
The balance of the specified account.
unScaledbalanceOf
Returns the unscaled(unaffected by pending rebalances) balance of the specified account.
This function returns the ERC20 balance(unaffected by pending rebalances) of the account.
function unScaledbalanceOf(address account) public view returns (uint256);
Parameters
account
address
The address of the account.
Returns
<none>
uint256
The unscaled(unaffected by pending rebalances) balance of the specified account.
hasPendingRebalance
Checks if the specified account has a pending rebalance.
Compares the account's last rebalance count with the current scalingfactor length to determine if a rebalance is pending.
function hasPendingRebalance(address account) public view returns (bool);
Parameters
account
address
The address of the account
Returns
<none>
bool
A boolean value indicating whether the specified account has a pending rebalance.
getTokenFactory
Retrieves the address of the Vault (TokenFactory) contract.
This function casts the tokenFactory
variable to an address and returns it.
function getTokenFactory() public view returns (address);
Returns
<none>
address
The address of the Vault (TokenFactory) contract.
transferFrom
Transfers the specified amount of tokens from the sender to the recipient.
Overrides the transferFrom
function from the inherited ERC20Upgradeable
and IERC20Upgradeable
contracts. If the sender or recipient has a pending rebalance, it is handled before the transfer. This function can only be called when transfers are not stopped, and neither the sender nor the recipient are on the sanctions list.
function transferFrom(address sender, address recipient, uint256 amount)
public
override(ERC20Upgradeable, IERC20Upgradeable)
stopTransfer
insufficientUnderlying
dailyFFUpdate
onlyNotSanctioned(recipient)
onlyNotSanctioned(sender)
returns (bool);
Parameters
sender
address
The address from which tokens will be transferred.
recipient
address
The address to which tokens will be transferred.
amount
uint256
The amount of tokens to transfer.
Returns
<none>
bool
A boolean value indicating whether the operation succeeded.
handlePendingRebalance
Handles pending rebalances for the sender and receiver addresses.
This function checks if the sender or receiver has a pending rebalance and applies the rebalance if needed.
function handlePendingRebalance(address sender, address receiver) public;
Parameters
sender
address
The address of the sender involved in a transfer operation.
receiver
address
The address of the receiver involved in a transfer operation.
asset
Retrieves the address of the underlying token.
It overrides the asset
function from the IERC4626Upgradeable
interface.
function asset() public view virtual override returns (address);
Returns
<none>
address
The address of the underlying token.
totalAssets
Retrieves the total amount of assets held by the TokenFactory.
It overrides the totalAssets
function from the IERC4626Upgradeable
interface.
function totalAssets() public view virtual override returns (uint256);
Returns
<none>
uint256
The total amount of assets held by the Vault(TokenFactory).
convertToShares
Converts a specified amount of underlying assets to shares(RiskOn/Off).
It overrides the convertToShares
function from the IERC4626Upgradeable
interface.
function convertToShares(uint256 assets) public view virtual override returns (uint256 shares);
Parameters
assets
uint256
The amount of assets to convert to shares.
Returns
shares
uint256
The amount of shares(RiskOn/Off) for the amount of assets.
convertToAssets
Converts a specified amount of shares(RiskOn/Off) to underlying assets.
It overrides the convertToAssets
function from the IERC4626Upgradeable
interface.
function convertToAssets(uint256 shares) public view virtual override returns (uint256 assets);
Parameters
shares
uint256
The amount of shares to convert to assets.
Returns
assets
uint256
The amount of assets for the amount of shares(RiskOn/Off).
maxDeposit
Calculates the maximum amount of assets that can be deposited by a specific account.
It overrides the maxDeposit
function from the IERC4626Upgradeable
interface.
function maxDeposit(address account) public view virtual override returns (uint256);
Parameters
account
address
The address of the account for which to calculate the maximum deposit amount.
Returns
<none>
uint256
The maximum amount of assets that can be deposited by the account.
previewDeposit
Provides a preview of the number of shares(RiskOn/Off) that would be received for a amount of assets.
It overrides the previewDeposit
function from the IERC4626Upgradeable
interface.
function previewDeposit(uint256 assets) public view virtual override returns (uint256);
Parameters
assets
uint256
The amount of assets to preview the deposit.
Returns
<none>
uint256
The amount of shares(RiskOn/Off) for the specified amount of assets.
deposit
Deposits an amount of underlying assets, crediting the shares(RiskON/OFF) to the receiver.
It overrides the deposit
function from the IERC4626Upgradeable
interface. The stopDeposit
circuit breaker can be used to freeze deposits and validateDepositAmount
modifier to validate the deposit amount
function deposit(uint256 assets, address receiver)
public
virtual
override
stopDeposit
insufficientUnderlying
dailyFFUpdate
depositLimitHit(assets)
validateDepositAmount(assets, receiver)
returns (uint256);
Parameters
assets
uint256
The amount of assets to deposit.
receiver
address
The receiver address.
Returns
<none>
uint256
The amount of shares(RiskOn/Off) the receiver will get.
depositWithPermit
Deposits an amount of underlying assets, crediting the shares(RiskON/OFF) to the receiver with an EIP-2612 permit for approval.
It overrides the deposit
function from the IERC4626Upgradeable
interface. The stopDeposit
circuit breaker can be used to freeze deposits and validateDepositAmount
modifier to validate the deposit amount then calls permit
on the underlyingToken
to set the allowance,
function depositWithPermit(uint256 assets, address receiver, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
public
stopDeposit
insufficientUnderlying
dailyFFUpdate
depositLimitHit(assets)
validateDepositAmount(assets, receiver)
returns (uint256);
Parameters
assets
uint256
The amount of underlying assets to deposit.
receiver
address
The address of the receiver
deadline
uint256
The deadline for the permit signature to be valid, as a UNIX timestamp.
v
uint8
The recovery byte of the signature.
r
bytes32
part of the ECDSA signature pair.
s
bytes32
part of the ECDSA signature pair.
Returns
<none>
uint256
The amount of shares(RiskOn/Off) the receiber will get
depositWithExpiry
Deposits an amount of underlying assets, crediting the shares(RiskON/OFF) to the receiver.
It overrides the deposit
function from the IERC4626Upgradeable
interface. The stopDeposit
circuit breaker can be used to freeze deposits and validateDepositAmount
modifier to validate the deposit amount
function depositWithExpiry(uint256 assets, address receiver, uint256 expiryDate)
public
virtual
expiryDateCheck(expiryDate)
stopDeposit
insufficientUnderlying
dailyFFUpdate
depositLimitHit(assets)
validateDepositAmount(assets, receiver)
returns (uint256);
Parameters
assets
uint256
The amount of assets to deposit.
receiver
address
The receiver address.
expiryDate
uint256
The expiry date for the deposit.
Returns
<none>
uint256
The amount of shares(RiskOn/Off) the receiver will get.
depositWithNative
Deposits an amount of underlying (NATIVE) assets, crediting the shares(RiskON/OFF) to the receiver.
It uses msg.value as the deposit amount. The stopDeposit
circuit breaker can be used to freeze deposits and validateDepositAmount
modifier to validate the deposit amount
function depositWithNative(address receiver)
public
payable
virtual
nonReentrant
stopDeposit
insufficientUnderlying
dailyFFUpdate
depositLimitHit(msg.value)
validateDepositAmount(msg.value, receiver)
returns (uint256);
Parameters
receiver
address
The receiver address.
Returns
<none>
uint256
The amount of shares(RiskOn/Off) the receiver will get.
maxMint
Calculates the maximum amount of shares(RiskOn/Off) that can be minted for a user.
It overrides the maxMint
function from the IERC4626Upgradeable
interface.
function maxMint(address account) public view virtual override returns (uint256);
Parameters
account
address
The address of user for which to calculate the maximum mintable shares(RiskOn/Off).
Returns
<none>
uint256
The maximum amount of shares(RiskOn/Off) that can be minted for the user.
previewMint
Provides a preview of the amount of underlying assets required to mint a number of shares(RiskOn/Off).
It overrides the previewMint
function from the IERC4626Upgradeable
interface.
function previewMint(uint256 shares) public view virtual override returns (uint256);
Parameters
shares
uint256
The number of shares(RiskOn/Off) to mint.
Returns
<none>
uint256
The amount of underlying assets required to mint the specified number of shares(RiskOn/Off).
mint
mints an amount of shares, crediting the shares(RiskON/OFF) to the receiver.
It overrides the deposit
function from the IERC4626Upgradeable
interface. The stopDeposit
circuit breaker can be used to freeze minting. As opposed to deposit, minting is allowed even if the vault is in a state where the price of a share is zero. In this case, the shares will be minted without requiring any assets to be deposited.
function mint(uint256 shares, address receiver)
public
virtual
override
stopDeposit
insufficientUnderlying
dailyFFUpdate
depositLimitHit(shares)
returns (uint256);
Parameters
shares
uint256
The amount of shares(RiskON/OFF) to mint.
receiver
address
The receiver address.
Returns
<none>
uint256
The amount of assets that were deposited to mint the specified number of shares(RiskON/OFF).
maxWithdraw
Calculates the maximum amount of underlying assets that can be withdrawn by a specified owner.
It overrides the maxWithdraw
function from the IERC4626Upgradeable
interface.
function maxWithdraw(address owner_) public view virtual override returns (uint256);
Parameters
owner_
address
The address of the owner for which to calculate the maximum underlying withdrawable assets.
Returns
<none>
uint256
The maximum amount of assets that can be withdrawn by the specified owner.
previewWithdraw
Provide a preview of number of shares(RiskOn/Off) required to withdraw an amount of underlying assets.
It overrides the previewWithdraw
function from the IERC4626Upgradeable
interface.
function previewWithdraw(uint256 assets) public view virtual override returns (uint256);
Parameters
assets
uint256
The amount of assets to withdraw.
Returns
<none>
uint256
The number of shares(RiskOn/Off) required to withdraw the specified amount of assets.
withdraw
Allows an owner to withdraw a specified amount of underlying assets, transferring them to a receiver.
This function overrides the withdraw
function from the IERC4626Upgradeable
interface, and is guarded by the stopWithdraw
, onlyAssetOwner
, and nonReentrant
modifiers.
function withdraw(uint256 assets, address receiver, address owner_)
public
virtual
override
stopWithdraw
insufficientUnderlying
dailyFFUpdate
withdrawLimitHit(assets)
onlyAssetOwner(owner_)
nonReentrant
returns (uint256);
Parameters
assets
uint256
The amount of underlying assets to withdraw.
receiver
address
The address to which the assets should be transferred.
owner_
address
The address of the owner making the withdrawal.
Returns
<none>
uint256
The number of shares(RiskON/OFF) corresponding to the withdrawn assets.
withdrawWithExpiry
Allows an owner to withdraw a specified amount of underlying assets, transferring them to a receiver.
This function overrides the withdraw
function from the IERC4626Upgradeable
interface, and is guarded by the stopWithdraw
, onlyAssetOwner
, and nonReentrant
modifiers.
function withdrawWithExpiry(uint256 assets, address receiver, address owner_, uint256 expiryDate)
public
virtual
expiryDateCheck(expiryDate)
stopWithdraw
insufficientUnderlying
dailyFFUpdate
withdrawLimitHit(assets)
onlyAssetOwner(owner_)
nonReentrant
returns (uint256);
Parameters
assets
uint256
The amount of underlying assets to withdraw.
receiver
address
The address to which the assets should be transferred.
owner_
address
The address of the owner making the withdrawal.
expiryDate
uint256
The expiry date for the withdrawal.
Returns
<none>
uint256
The number of shares(RiskON/OFF) corresponding to the withdrawn assets.
flashLoan
Allows user to take flashloans from the tokenFactory (Vault/POOL)
This function is guarded by the nonReentrant
and stopFlashLoan
modifiers. It makes use of AAVE's flashloan interface to provide backwards compatibility for ease of use
function flashLoan(address receiver, uint256 amount, bytes memory params)
external
nonReentrant
stopFlashLoan
onlyNotSanctioned(receiver)
onlyNotSanctioned(_msgSender());
Parameters
receiver
address
The address of the receiver.
amount
uint256
The amount of underlying assets to flashloan.
params
bytes
The parameters for the flashloan. Used by the receiver contract(Aave's interface)
maxRedeem
Computes the maximum amount of underlying assets that can be redeemed by owner.
It overrides the maxRedeem
function from the IERC4626Upgradeable
interface.
function maxRedeem(address owner_) public view virtual override returns (uint256);
Parameters
owner_
address
The address of the owner.
Returns
<none>
uint256
The maximum amount of underlying assets that the owner can redeem.
previewRedeem
Provides a preview of the amount of underlying assets that would be received when redeeming a number of shares(RiskON/OFF).
It overrides the previewRedeem
function from the IERC4626Upgradeable
interface.
function previewRedeem(uint256 shares) public view virtual override returns (uint256);
Parameters
shares
uint256
The number of shares(RiskON/OFF) to compute the equivalent underlying asset amount for.
Returns
<none>
uint256
The equivalent asset amount for the given number of shares(RiskON/OFF).
redeem
Allows a user to redeem some amount of underlying assets based on an input amount of shares(RiskON/OFF).
See IERC4626-redeem.
It overrides the redeem
function from the IERC4626Upgradeable
interface. and is guarded by the stopWithdraw
, onlyAssetOwner
, and nonReentrant
modifiers.
function redeem(uint256 shares, address receiver, address owner_)
public
virtual
override
stopWithdraw
insufficientUnderlying
dailyFFUpdate
withdrawLimitHit(shares)
onlyAssetOwner(owner_)
nonReentrant
returns (uint256);
Parameters
shares
uint256
The number of shares(RiskON/OFF) to redeem for underlying assets.
receiver
address
The address of receiver.
owner_
address
The address of the owner.
Returns
<none>
uint256
The amount of underlying assets redeemed.
_onlyTokenFactory
Helpers for modifiers to reduce size
Checks if the caller is the Vault (tokenFactory)
This function is utilized by the onlyTokenFactory
modifier to ensure that only the token factory can call certain functions.
function _onlyTokenFactory() private view;
_onlyAssetOwner
Checks if the caller is the asset owner.
This function is utilized by the onlyAssetOwner
modifier to ensure that only the asset owner can call certain functions.
function _onlyAssetOwner(address assetOwner) private view;
Parameters
assetOwner
address
The address of the asset owner.
_validateDepositAmount
Validates the deposit amount.
This function is utilized by the validateDepositAmount
modifier to ensure that the deposit amount is neither zero nor exceeds the maximum allowed deposit for the receiver.
function _validateDepositAmount(uint256 assets, address receiver) private view;
Parameters
assets
uint256
The amount of underlying assets being deposited.
receiver
address
The address of the receiver
hasPendingFF
function hasPendingFF(address account) public view returns (bool);
handlePendingFF
function handlePendingFF(address sender, address receiver) public;
_handleDeposit
function _handleDeposit(uint256 assets, address receiver) private returns (uint256);
Parameters
assets
uint256
The amount of underlying assets to deposit.@note WE can use SHARES as well since it's a 1:1 conversion
receiver
address
The address to which the assets should be transferred.
_handleWithdraw
function _handleWithdraw(uint256 assets, address receiver, address owner_) private returns (uint256);
Parameters
assets
uint256
The amount of underlying assets to withdraw. @note WE can use SHARES as well since it's a 1:1 conversion
receiver
address
The address to which the assets should be transferred.
owner_
address
The address of the owner making the withdrawal.
getFlashLoanPool
Retrieves the address of the flashloan POOL (TokenFactory) contract.
This function casts the tokenFactory
variable to an address and returns it.
function getFlashLoanPool() public view returns (address);
Returns
<none>
address
The address of the flashloan POOL (TokenFactory) contract.
Errors
SmartToken__NotTokenFactory
error SmartToken__NotTokenFactory();
SmartToken__MethodNotAllowed
error SmartToken__MethodNotAllowed();
SmartToken__DepositMoreThanMax
error SmartToken__DepositMoreThanMax();
SmartToken__MintMoreThanMax
error SmartToken__MintMoreThanMax();
SmartToken__WithdrawMoreThanMax
error SmartToken__WithdrawMoreThanMax();
SmartToken__RedeemMoreThanMax
error SmartToken__RedeemMoreThanMax();
SmartToken__OnlyAssetOwner
error SmartToken__OnlyAssetOwner();
SmartToken__ZeroDeposit
error SmartToken__ZeroDeposit();
SmartToken__InsufficientUnderlying
error SmartToken__InsufficientUnderlying();
SmartToken__DepositLimitHit
error SmartToken__DepositLimitHit();
SmartToken__WithdrawLimitHit
error SmartToken__WithdrawLimitHit();
SmartToken__ExpiryDateReached
error SmartToken__ExpiryDateReached();
SmartToken__WithdrawNativeFailed
error SmartToken__WithdrawNativeFailed();
Last updated