Token Factory

TokenFactory

Git Source

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

Name
Type
Description

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

Name
Type
Description

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

Name
Type
Description

asset_

IERC20

The address of the underlying token

Returns

Name
Type
Description

<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

Name
Type
Description

<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

Name
Type
Description

<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

Name
Type
Description

owner_

address

The address of the owner

Returns

Name
Type
Description

<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

Name
Type
Description

owner_

address

The address of the owner

Returns

Name
Type
Description

<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

Name
Type
Description

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

Name
Type
Description

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

Name
Type
Description

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

Name
Type
Description

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

Name
Type
Description

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

Name
Type
Description

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

Name
Type
Description

owner_

address

The address of the owner

Returns

Name
Type
Description

<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

Name
Type
Description

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

Name
Type
Description

signature

bytes

The signature to be verified.

encodedData

bytes

The data to be decoded into a ScheduledRebalance struct.

Returns

Name
Type
Description

<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

Name
Type
Description

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

Name
Type
Description

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

Name
Type
Description

<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

Name
Type
Description

state

bool

The new state of management fee collection.

Returns

Name
Type
Description

<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

Name
Type
Description

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

Name
Type
Description

<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

Name
Type
Description

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

Name
Type
Description

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

Name
Type
Description

addr

address

The address of the signer

Returns

Name
Type
Description

<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

Name
Type
Description

sequenceNumber

uint256

The sequence number of the scheduledRebalances mapping to retrieve.

Returns

Name
Type
Description

<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

Name
Type
Description

<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

Name
Type
Description

<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

Name
Type
Description

<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

Name
Type
Description

index

uint8

The index of the SmartToken in the smartTokenArray.

Returns

Name
Type
Description

<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

Name
Type
Description

<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

Name
Type
Description

<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