Token Factory
TokenFactory
Inherits: ReentrancyGuardUpgradeable, OwnableUpgradeable, UUPSUpgradeable, BaseContract
The main purposes of this contract is to act as a vault as well as it contains the shared logic used by riskON/OFF tokens.
Acts as the vault for holding the underlying assets/tokens. Also contains shared logic used by riskON/OFF
State Variables
rebalanceElements
RebalanceElements[] private rebalanceElements;
dailyFeeFactors
uint256[] private dailyFeeFactors;
userRebalanceElements
mapping(address => UserRebalanceElements) private userRebalanceElements;
REBALANCE_INT_MULTIPLIER
uint256 private constant REBALANCE_INT_MULTIPLIER = 10 ** 18;
smartTokenArray
SmartToken[] private smartTokenArray;
lastRebalanceCount
This mapping keeps track of the last rebalance applied to a user/address
mapping(address => uint256) private lastRebalanceCount;
lastdailyFFcount
mapping(address => uint256) private lastdailyFFcount;
baseToken
This is the instance of the underlying Token
IERC20Update private baseToken;
baseTokenDecimals
The number of decimals of the underlying Asset/Token
uint8 private baseTokenDecimals;
interval
The rebalance interval in seconds
uint256 private interval;
lastTimeStamp
The timestamp of the last rebalance
uint256 private lastTimeStamp;
smartTokenInitialized
This boolean keeps track if the smart tokens(RiskON/OFF) have already been initialized in the system
bool private smartTokenInitialized;
signers
This is the signers address of RP api's that generate encoded params for rebalance
mapping(address => bool) private signers;
FFinterval
This is used by the feefactors method to calculate the fees
uint256 private FFinterval;
FFLastTimeStamp
uint256 private FFLastTimeStamp;
sequenceNumberApplied
This keeps track of the 'sequenceNumber' of a rebalance which helps
mapping(uint256 => bool) private sequenceNumberApplied;
managementFeesRate
uint256 private managementFeesRate;
managementFeesRateRebalance
uint256 private managementFeesRateRebalance;
managementFeeEnabled
bool private managementFeeEnabled;
lastRebalanceFees
uint256 private lastRebalanceFees;
treasuryWallet
address private treasuryWallet;
orchestrator
address private orchestrator;
isNativeToken
bool private isNativeToken;
premiumPercentage
uint16 private premiumPercentage;
premiumCharged
uint256 private premiumCharged;
scheduledRebalances
A mapping to hold the scheduled rebalances. This helps in storing rebalances in the order they are scheduled till they are all executed
mapping(uint256 => Shared.ScheduledRebalance) private scheduledRebalances;
scheduledRebalancesLength
uint256 private scheduledRebalancesLength;
nextSequenceNumber
A counter to generate a unique sequence number for each rebalance. This ensures that rebalances are executed in the order they are scheduled.
uint256 private nextSequenceNumber;
period
uint256 private period;
withdrawLimit
uint256 private withdrawLimit;
depositLimit
uint256 private depositLimit;
hasWithdrawLimit
bool private hasWithdrawLimit;
hasDepositLimit
bool private hasDepositLimit;
currentWithdrawPeriodEnd
mapping(address => uint256) private currentWithdrawPeriodEnd;
currentWithdrawPeriodAmount
mapping(address => uint256) private currentWithdrawPeriodAmount;
currentDepositPeriodEnd
mapping(address => uint256) private currentDepositPeriodEnd;
currentDepositPeriodAmount
mapping(address => uint256) private currentDepositPeriodAmount;
Functions
onlySmartTokens
Ensures the caller is one of the SmartTokens(RiskOn/Off).
This modifier checks if the caller is either smartTokenArray[0] or smartTokenArray[1]. If not, it reverts with a custom error message.
modifier onlySmartTokens();
onlyOrchestrator
modifier onlyOrchestrator();
onlyIntializedOnce
modifier onlyIntializedOnce();
constructor
constructor();
initialize
Initializes(replacement for the constructor) the Vault (TokenFactory) contract with specified params
This function sets up the initial state of the TokenFactory contract. Callable only once.
function initialize(
IERC20Update baseTokenAddress,
uint256 rebalanceInterval,
uint256 ffInterval,
address sanctionsContract_,
address signersAddress_,
address owner_,
uint256 withdrawLimit_,
uint256 depositLimit_,
uint256 limitPeriod_,
bool isNativeToken_
) public initializer;
Parameters
baseTokenAddress
IERC20Update
The address of the underlying token/asset
rebalanceInterval
uint256
The interval (in seconds) at which natural rebalances are scheduled.
ffInterval
uint256
sanctionsContract_
address
The address of the sanctions contract(chainalysis contract) to verify blacklisted addresses
signersAddress_
address
The address of the signer ( RP Api's) which signed the rebalance data
owner_
address
withdrawLimit_
uint256
depositLimit_
uint256
limitPeriod_
uint256
isNativeToken_
bool
_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(UUPSUpgradeable) onlyOwner;
initializeSMART
Initializes the smart tokens associated with this TokenFactory. renaming this method to avoid conflicts with upgradable initialize
This function can only be called once, and only by the contract owner.
function initializeSMART(SmartToken token1, SmartToken token2) external onlyOwner onlyIntializedOnce;
Parameters
token1
SmartToken
The first smart token
token2
SmartToken
The second smart token
initializeOrchestrator
function initializeOrchestrator(address orchestrator_) external onlyOwner;
_tryGetAssetDecimals
Attempts to fetch the decimals of underlying token
This function uses a static call to query the decimals from the asset. If the call fails or the returned data is invalid, it defaults to 0.
function _tryGetAssetDecimals(IERC20 asset_) private view returns (bool, uint8);
Parameters
asset_
IERC20
The address of the underlying token
Returns
<none>
bool
A return vaule containing a boolean indicating success and the decimals of the token. or false if it failed somehow
<none>
uint8
decimals
Fetches the decimal value of the underlying token
This function returns the value of decimals that was set in the 'initialize' method
function decimals() public view virtual returns (uint8);
Returns
<none>
uint8
The number of decimals of the underlying token
getBaseToken
Retrieves the instance of the underlying token contract
This function provides a way to access the instance of the underlying contract
function getBaseToken() public view virtual returns (IERC20Update);
Returns
<none>
IERC20Update
The instance of the underlying contract
maxAmountToWithdraw
Returns the maximum amount of assets the owner can withdraw.
This function compares the balance of both smart tokens(RiskON/OFF) for the owner and returns the balance of the smart token with the lesser amount.
function maxAmountToWithdraw(address owner_) public view virtual returns (uint256);
Parameters
owner_
address
The address of the owner
Returns
<none>
uint256
The maximum amount of assets the specified owner can withdraw.
maxSharesOwned
Determines the maximum amount of shares owned by the owner
This function compares the balance of both smart tokens(RiskON/OFF) for the owner and returns the balance of the smart token with the greater amount.
function maxSharesOwned(address owner_) public view virtual returns (uint256);
Parameters
owner_
address
The address of the owner
Returns
<none>
uint256
The maximum amount of shares owned by the specified owner.
_deposit
Deposit/mint common workflow, deposit underlying tokens, mints new shares(RiskON/OFF) to the receiver, and also charges management fees
Deposit/mint common workflow.
This function can only be called by the smart tokens and requires the caller and receiver to not be sanctioned.
function _deposit(address caller, address receiver, uint256 assets, uint256 shares)
external
virtual
onlyNotSanctioned(caller)
onlyNotSanctioned(receiver)
onlySmartTokens;
Parameters
caller
address
The address of depositor
receiver
address
The address of receiver
assets
uint256
The amount of underlying tokens being deposited.
shares
uint256
The amount of shares(RiskON/OFF) to mint to the receiver.
_withdraw
Withdraw/redeem common workflow. Handles the withdrawal of underlying token. burns shares(RiskON/OFF) from the caller, and refund any management fees
This function can only be called by the smart tokens and requires the caller and receiver to not be sanctioned.
function _withdraw(address caller, address receiver, address owner, uint256 assets, uint256 shares)
external
virtual
onlyNotSanctioned(caller)
onlyNotSanctioned(receiver)
onlySmartTokens;
Parameters
caller
address
The address withdrawing.
receiver
address
The address receiving the underlying token.
owner
address
The owner of the shares.
assets
uint256
The amount of underlying Token being withdrawn.
shares
uint256
The amount of shares(RiskON/OFF) to burn from the caller.
getUserRecords
function getUserRecords(address sender, address recipient) external view onlySmartTokens returns (uint256[4] memory);
transferRecords
function transferRecords(
address sender,
address recipient,
bool tokenType,
uint256 amount,
uint256 prevBalXsender,
uint256 prevBalYsender,
uint256 prevBalXrecipient,
uint256 prevBalYrecipient
) external onlySmartTokens;
updateRecord
function updateRecord(bool tokenType, address account, uint256 amount) external onlySmartTokens;
updateRecord
function updateRecord(bool tokenType, uint256 amount) external onlySmartTokens;
factoryMint
Mints the specified amount of Shares(RiskON/OFF) to the receiver
It first previews the minting process to get the amount of Shares(RiskON/OFF)that will be minted, and then performs the actual minting.
function factoryMint(uint256 smartTokenIndex, address receiver, uint256 amount) private;
Parameters
smartTokenIndex
uint256
The index of the smart token in the smartTokenArray.
receiver
address
The address of the receiver
amount
uint256
The amount of Shares(RiskON/OFF) to mint.
factoryBurn
Burns the specified amount of Shares(either of RiskON/OFF)from the owner
It calls the burn
function on the smart token contract
function factoryBurn(uint256 smartTokenIndex, address owner_, uint256 amount) private;
Parameters
smartTokenIndex
uint256
The index of the smart token in the smartTokenArray
.
owner_
address
The address of the owner
amount
uint256
The amount of Shares(either of RiskON/OFF) to burn.
factoryTreasuryTransfer
function factoryTreasuryTransfer(uint256 amount) private;
factoryBalanceAdjust
function factoryBalanceAdjust(address account, uint256 amountX, uint256 amountY) private;
executeRebalance
Executes a rebalance based on the provided encoded data and signature.
This function validates the rebalance call, schedules it, and possibly triggers a rebalance if the sequence is in order. It first verifies the signature of the rebalance params with the signer's public key. Then we verify if the sequence number is aligned and not already used. Then we push the rebalance params into an array of scheduled rebalances. Finally, if there is no gaps between the previous rebalance'sequence number, we execute this rebalance This function can only be called when rebalance is not stopped with the stopRebalance
modifier.
function executeRebalance(bytes memory encodedData, bytes memory signature) external stopRebalance onlyOrchestrator;
Parameters
encodedData
bytes
The encoded data containing the sequence number, the boolean value for natural rebalance and the price of underlying and smartTokenX
signature
bytes
The signature of the encoded data to verify its authenticity.
executeScheduledRebalances
Executes scheduled rebalances pending in the queue
This function is called when the scheduled rebalance queue had more than 5 entries only 5 will be executed and the rest will be left in the queue
function executeScheduledRebalances() external stopRebalance onlyOrchestrator;
chargeFees
Charges the management fees
This function is responsible for charging the fees of the whole universe and related functionalities. We charge the fees on a daily Basis/ each FFinterval
function chargeFees() private;
rebalance
Handles the actual rebalancing mechanism.
This function processes up to 5 scheduled rebalances per call. Different factors that will help calculating user balances are calculated here using the rebalance params.
function rebalance() private;
updateFeeFactor
function updateFeeFactor() private;
dailyFeeFactorsUpdate
function dailyFeeFactorsUpdate() public;
applyFF
should apply this to users before any interaction with the contracts
function applyFF(address owner) public;
updateUserLastFFCount
function updateUserLastFFCount(address owner_) public;
FFCheck
function FFCheck(address user) private;
applyRebalance
Applies rebalance to an account
This function adjusts the balance of smart tokens(RiskON/RiskOFF) according to the rollOverValue. This function can only be called when rebalance is stopped. It also calculates and applies management fees.
function applyRebalance(address owner_) public stopRebalance;
Parameters
owner_
address
The address of the account to which the rebalance will be applied.
underlyingTransfer
function underlyingTransfer(address receiver_, uint256 amount_) external onlySmartTokens;
underlyingReturn
function underlyingReturn(address sender_, uint256 amount_, uint256 premium) external onlySmartTokens;
calculateRollOverValue
Calculates the rollover value(Units of RiskON/OFF) for an account
This function calculates the net balance(Units of RiskON/OFF) of a user after rebalance and management fees are applied.
function calculateRollOverValue(address owner_) public view returns (uint256, uint256);
Parameters
owner_
address
The address of the owner
Returns
<none>
uint256
The calculated roll over value.
<none>
uint256
updateUserLastRebalanceCount
Updates the last rebalance count of a user.
This function sets the last rebalance count for a user if their unscaled balances for both smart tokens(RiskON/RiskOFF) are zero. We may use this in cases where a receiever is new to the system
function updateUserLastRebalanceCount(address owner_) public;
Parameters
owner_
address
The address of the user
verifyAndDecode
Verifies the provided signature and decodes the encoded data into ScheduledRebalance
struct.
It recovers the address from the Ethereum signed message hash and the provided signature
. If the recovered address doesn't match the signersAddress
, it reverts the transaction. If the signature is valid, it decodes the encodedData
into a ScheduledRebalance
struct and returns it.
function verifyAndDecode(bytes memory signature, bytes memory encodedData)
public
view
returns (Shared.ScheduledRebalance memory);
Parameters
signature
bytes
The signature to be verified.
encodedData
bytes
The data to be decoded into a ScheduledRebalance
struct.
Returns
<none>
Shared.ScheduledRebalance
data A ScheduledRebalance
struct containing the decoded data.
setSignersAddress
Update the address authorized to sign rebalance transactions.
This function can only be called by the owner of the contract. It updates the signersAddress
address with the provided addr
address.
function setSignersAddress(address addr) external onlyOwner;
Parameters
addr
address
The new address
removeSigner
function removeSigner(address signer) external onlyOwner;
setManagementFeeRate
Updates the rate of management fees.
It updates the managementFeesRate
state variable with the provided rate
value, if the rate is within a valid range, otherwise, it reverts the transaction. The rate is in terms of percentage per day scaling factor is 10E18 Example 5% per day = 0.0510E18*
function setManagementFeeRate(uint256 rate, uint256 rateRebalance) external onlyOwner returns (bool);
Parameters
rate
uint256
The new rate of management fees. It is DAILY RATE
rateRebalance
uint256
The new rate of management fees for rebalance.(REBALANCE RATE)
Returns
<none>
bool
A boolean value
setManagementFeeState
Toggles the state of management fee collection.
This function can only be called by the contract owner. It either enables or disables the management fee collection
function setManagementFeeState(bool state) external onlyOwner returns (bool);
Parameters
state
bool
The new state of management fee collection.
Returns
<none>
bool
A boolean value
setTreasuryWallet
function setTreasuryWallet(address wallet) external onlyOwner returns (bool);
calculateManagementFee
Calculates the management fee for a given amount over a particular time span.
It computes the management fee either using the default management fee rate or a provided fee rate. This function can be used both for deposit and withdrawal scenarios.
function calculateManagementFee(uint256 amount, uint256 mgmtFee) public view returns (uint256);
Parameters
amount
uint256
The amount of RiskON/OFF to calculate the fee against.
mgmtFee
uint256
The management fee rate to use if isDefault
is set to false.
Returns
<none>
uint256
userFees The calculated management fee
rebalanceCheck
Checks if a user is an existing user and applies user rebalance when needed.
This function is triggered to ensure a user's balances are updated with any rebalances that have occurred since their last interaction with the contract.
function rebalanceCheck(address user) private;
Parameters
user
address
The address of the user
removeRebalance
Removes a rebalance entry from the scheduledRebalances
mapping at the given sequence number.
It deletes the entry at the given sequence number and decrements the scheduledRebalancesLength
variable. It is also guarded by 'nonReentrant' modifier.
function removeRebalance(uint256 sequenceNumber) private nonReentrant;
Parameters
sequenceNumber
uint256
The sequenceNumber of the scheduledRebalances
mapping to remove.
isValidSigner
Verifies if a signer is valid
Verifies if a signer is valid
function isValidSigner(address addr) public view returns (bool);
Parameters
addr
address
The address of the signer
Returns
<none>
bool
true if signer is valid
withdrawLimitMod
ratelimits
function withdrawLimitMod(uint256 amount) external onlySmartTokens returns (bool);
depositLimitMod
function depositLimitMod(uint256 amount) external onlySmartTokens returns (bool);
updatePeriod
function updatePeriod(
address user,
mapping(address => uint256) storage currentPeriodEnd,
mapping(address => uint256) storage currentPeriodAmount
) internal;
updateWithdrawLimit
function updateWithdrawLimit(uint256 newLimit) external onlyOwner;
updateDepositLimit
function updateDepositLimit(uint256 newLimit) external onlyOwner;
updateLimitPeriod
function updateLimitPeriod(uint256 newPeriod) external onlyOwner;
toggleWithdrawLimit
function toggleWithdrawLimit() external onlyOwner;
toggleDepositLimit
function toggleDepositLimit() external onlyOwner;
setPremiumPercentage
function setPremiumPercentage(uint16 percentage) external onlyOwner;
drainFlashloanPremiums
function drainFlashloanPremiums(address receiver) external onlyOwner;
getScheduledRebalances
Retrieves the scheduledRebalance
struct at the given sequence number.
This function is a getter for a single scheduledRebalance
struct.
function getScheduledRebalances(uint256 sequenceNumber) public view returns (Shared.ScheduledRebalance memory);
Parameters
sequenceNumber
uint256
The sequence number of the scheduledRebalances
mapping to retrieve.
Returns
<none>
Shared.ScheduledRebalance
The scheduledRebalance
struct at the given sequence number.
getNextSequenceNumber
Retrieves the nextSequenceNumber
This function is a getter for the nextSequenceNumber
variable.
function getNextSequenceNumber() public view returns (uint256);
Returns
<none>
uint256
The anextSequenceNumber
getLastTimeStamp
Retrieves the lastTimeStamp
This function is a getter for the lastTimeStamp
variable.
function getLastTimeStamp() external view onlyOwner returns (uint256);
Returns
<none>
uint256
The lastTimeStamp
getManagementFeeRate
function getManagementFeeRate() public view returns (uint256, uint256);
getManagementFeeState
Retrieves the managementFeeEnabled
This function is a getter for the managementFeeEnabled
variable.
function getManagementFeeState() public view returns (bool);
Returns
<none>
bool
The managementFeeEnabled
getRebalanceNumber
function getRebalanceNumber() public view returns (uint256);
getUserLastRebalanceCount
function getUserLastRebalanceCount(address userAddress) public view returns (uint256);
getSmartTokenAddress
Retrieves the interval
This function is a getter for the interval
variable.
function getSmartTokenAddress(uint8 index) public view returns (SmartToken);
Parameters
index
uint8
The index of the SmartToken in the smartTokenArray
.
Returns
<none>
SmartToken
The interval
getTreasuryAddress
function getTreasuryAddress() public view returns (address);
getInterval
Retrieves the interval
This function is a getter for the interval
variable.
function getInterval() public view returns (uint256);
Returns
<none>
uint256
The interval
insufficientUnderlying
Validates if the amount of underlying locked in the token factory is
This function is used the smartoken modifer
function insufficientUnderlying() external view returns (bool);
Returns
<none>
bool
true if underlying is less
withdrawLimitStatus
function withdrawLimitStatus() public view returns (bool);
depositLimitStatus
function depositLimitStatus() public view returns (bool);
getWithdrawLimit
function getWithdrawLimit() public view returns (uint256);
getDepositLimit
function getDepositLimit() public view returns (uint256);
getLimitPeriod
function getLimitPeriod() public view returns (uint256);
getUserLimitPerPeriod
function getUserLimitPerPeriod(address user, bool isWithdraw)
public
view
returns (uint256 periodEnd, uint256 currentAmount);
getLastFFTimeStamp
Getters for the new fees mechanisms
function getLastFFTimeStamp() external view returns (uint256);
getDailyFeeFactorNumber
function getDailyFeeFactorNumber() public view returns (uint256);
getUserLastFFCount
function getUserLastFFCount(address userAddress) public view returns (uint256);
getIsNativeToken
function getIsNativeToken() public view returns (bool);
getFlashloanPremium
function getFlashloanPremium() public view returns (uint16);
getAccumulatedFlashLoanPremium
function getAccumulatedFlashLoanPremium() public view returns (uint256);
Events
RebalanceApplied
event RebalanceApplied(address userAddress, uint256 rebalanceCount);
Rebalance
event Rebalance(uint256 rebalanceCount);
Deposit
event Deposit(address caller, address receiver, uint256 assets, uint256 shares);
Withdraw
event Withdraw(address caller, address receiver, address owner, uint256 assets, uint256 shares);
PremiumDrained
event PremiumDrained(address receiver, uint256 amount);
WithdrawLimitToggled
event WithdrawLimitToggled(bool enabled);
DepositLimitToggled
event DepositLimitToggled(bool enabled);
Errors
TokenFactory__MethodNotAllowed
error TokenFactory__MethodNotAllowed();
TokenFactory__InvalidDivision
error TokenFactory__InvalidDivision();
TokenFactory__InvalidRebalanceParams
error TokenFactory__InvalidRebalanceParams();
TokenFactory__InvalidSequenceNumber
error TokenFactory__InvalidSequenceNumber();
TokenFactory__InvalidNaturalRebalance
error TokenFactory__InvalidNaturalRebalance();
TokenFactory__AlreadyInitialized
error TokenFactory__AlreadyInitialized();
TokenFactory__InvalidSignature
error TokenFactory__InvalidSignature();
TokenFactory__InvalidSignatureLength
error TokenFactory__InvalidSignatureLength();
TokenFactory__InvalidManagementFees
error TokenFactory__InvalidManagementFees();
TokenFactory__SmartTokenArrayOutOfBounds
error TokenFactory__SmartTokenArrayOutOfBounds();
TokenFactory__NoPremiumsToDrain
error TokenFactory__NoPremiumsToDrain();
Structs
RebalanceElements
struct RebalanceElements {
uint256 BalanceFactorXY;
uint256 BalanceFactorUx;
uint256 BalanceFactorUy;
}
UserRebalanceElements
struct UserRebalanceElements {
uint256 netX;
uint256 netY;
uint256 Ux;
uint256 Uy;
}
Last updated