Core
There are several basic principles that shape the design of the Euclidean Protocol Permissionless Vaults protocol:
Liquidity put into protocol can always be withdrawn (but, maybe not through one block, because we have a withdrawal limit for a single block in order to protect us from potential attacks). That is governance, strategy or any other entity cannot preclude a Liquidity Provider from withdrawing the funds.
Actions of Strategist or Governance that change substantial protocol parameters undergo some time between the moment changes are proposed in the contract (so anybody can see this proposal) and the moment they are effectively staged (typically 1 day).
Strategy actions are limited by the permissions of the particular Vault System.
Everyone can create a Vault System ready for accepting deposits by Liquidity Providers and managing the liquidity by the Strategy.
The Strategy is an arbitrary contract constrained by the Vault System permissions system
Vault groups
A vault group is a set of entities that manage Vaults of a specific Vault kind. It is used to create a new Vault or manage Vault params. It has 3 main entities:
Vault Governance is a contract that contains a set of parameters for a specific Vault kind managed by a Strategist or Governance. The params are defined by being:
Being instant or delayed (changes take into effect after some delay, which is set in the Protocol Governance)
Being applied to all Vaults in the Vault Group System or to some specific vaults
Being managed by a Strategist or by Governance.
Vault Factory is a singleton instance of a certain Vault kind, serving as a prototype for all vaults of the Vault Group
Vault instances (pink color), where each new vault is created using EIP-1167 lightweight proxy clone from Vault Factory
Vault Governance
We have several Vault kinds, and, as stated above, any Vault kind has its own Vault Governance. Any governance, in its turn, has its own parameters. You may explore the info about those parameters in this section.
Protocol Governance
Protocol governance manages the global parameters of the protocol. You may see those parameters in this section.
Withdrawal limits
For each withdrawn token, there's a per block limit = withdrawLimit * unitPrices[token]. This is used mainly for the flashloan attacks protection as a potential attacker couldn't withdraw large amounts from the pool in one block.
To protect the protocol from the governance hijack DDOS attack (set withdraw limit to 0), the minimum threshold of 200_000 USD for withdrawLimit is hardcoded. The other vector of attack could be setting unitPrices to 0 but that's mitigated by the required 14 days delay to update prices.
Given the above, unitPrices don't need to be updated very frequently as they are used only for withdrawals limit (used only for protection from attacks). For example, the ETH price of 1500 USD / ETH could be used for months.
Permissions
ProtocolGovernance manages the permission system for other vaults. The ProtocolGovernance itself doesn't impose any restrictions with these permissions, rather it's only the data used by Vaults to impose restrictions. Each permission is a mapping from the address to a bitmask.
The latest two permissions are made in order to prevent transferring funds to relatively unknown protocols from any strategy but to remain this right for strategies we verify as Trusted.
Note: forceAllowMask
in protocolParams overrides the permission for all addresses (if a bit in this mask is set)
Roles
ADMIN: allowed to update any params and assign ADMIN and ADMIN_DELEGATE roles
ADMIN_DELEGATE: allowed to update any params
OPERATOR: allowed to operate certain actions in strategies, which are determined by a strategist (for example, make rebalances or swaps of tokens when needed, typically a role for an off-chain bot that manages a strategy)
Validators
ProtocolGovernance also manages a set of validators for external calls (calls a Strategy can do on behalf of Vault). A validator is a contract that verifies that an external call is made in a good faith with correct parameters.
ProtocolGovernance has a mapping of an address to a validator. The Governance may set a validator for an address. If there is no validator for an address, an external call to this address is forbidden. Otherwise, the validator checks if the call is valid, using ProtocolGovernance permissions and other validation logic.
System management
There are several levels of management in the Euclidean Protocol:
Admin of the protocol is a head body, which governs the protocol and also grants or revokes the admin delegate role, hence exercising control over that entity (below). This will be governed by the Euclidean DAO voting and implemented via special-purpose multi-sig wallets.
Admin delegate is an entity that normally governs the major parameters of the protocol and grants other Strategists rights to join our system.
A Vault System and a corresponding strategy are normally governed by a Strategist. In case this is one of our strategies, it's governed by a multi-sig wallet controlled by our team members, which owns VaultRegistry NFTs of the Vault System vaults and controls strategy parameters by changing them using rights of those NFTs (typically, through changing strategy parameters of the ERC20RootVault)
VaultRegistry
VaultRegistry stores information about all open vaults.
The registry adheres to the ERC721 standard: each Vault is assigned an NFT. The semantics is that the NFT owner would be the ERC20Root vault that manages the actions of liquidity providers (i.e. deposits or withdraws tokens from vaults when needed), whereas the NFT approved address would be a Strategy, which is responsible for rebalancing tokens between vaults inside a Vault System.
Oracles
Oracles are used for estimating the price of token X to token Y. Euclidean Protocol oracle has 5 price safety levels:
Spot price - exact price, but easy to manipulate
UniV3 TWAP for 2.5 munites - somewhat stale price, but harder to manipulate
Same as 2 but for 7.5 minutes
Same as 2 but for 30 minutes
Chainlink oracle
The oracle is to be queried with a mask of desired safety levels. The oracle would take prices for all specified safety levels which are available for this pair of tokens and return the average of them.
Deposits / Withdrawals
Deposits are made through ERC20RootVault in several steps:
For every token, the higher estimate of its TVL in the whole system is fetched (each vault has 2 TVL estimates - higher and lower. The discrepancies in TVLs data are caused by different oracles price discrepancies. A mask of oracle safety levels is typically hardcoded inside a vault's code)
Deposited tokens are used in the same ratio as in the TVL estimate. All the amounts that exceed those needed for keeping this ratio are returned back to the depositor.
Tokens are transferred into ERC20RootVault
The shares of deposited tokens to the TVL estimate are calculated for each token. Minumum is calculated
Using the minimum in step 4 and the total LP supply, the LP tokens amount is calculated and minted
The withdrawal is made similarly but with some modifications:
For every token, the lower estimate of its TVL in the whole system is fetched
LP tokens amount desired to be burned by a withdrawer, total LP supply, and the lower estimate of TVL are used to calculate each token amount pending withdrawal
ERC20RootVault transfers those tokens from the first subvault (typically ERC20Vault) in the Vault System. If those amounts are not enough then it goes to the 2nd subvault, etc.
After ERC20RootVault has enough tokens on balance it burns lp tokens and transfers ERC20 tokens to withdrawer
All leftovers are transferred to the first subvault
Withdrawal amounts are subject to withdrawal limits imposed by ProtocolGovernance.
Fees
Every period of time (set in the managementFeeChargeDelay
parameter of ERC20Root vault), certain fees are charged to all the users (charging fees is triggered by any deposit or withdrawal, but done only if the set period of time from the latest charging has passed). Due annual fees rates are set in the ERC20RootVault parameters (see above).
Management and protocol fees are charged by the elapsed time, at a rate correspondingly proportional to the rate of the annual fee, from all the users, in form of minting new LP tokens for the benefit of the protocol Treasury.
Performance fees are charged only if the value of 1 LP token has increased from its ATH. In this case, the fee is charged at the established rate on the increase of the value of all LP tokens, in form of minting new LP tokens for the benefit of the protocol Treasury.
Rebalances
To rebalance tokens between the vaults pull
method is used (available for anyone approved for ERC721 vault NFT). If it's called on any subvault except the first, it pulls tokens into the first vault. If it's called on the first vault then tokens can be pulled to any Vault of the Vault System.
To rebalance tokens within the first vault externalCall
function is typically used. External calls are allowed to be called by Strategy on behalf of the Vault to external DEXes like Uniswap and Curve.
Last updated