Curve Pool Factories allow the permissionless deployment of liquidity pools, gauges, and LP tokens.
Every Factory contract from Curve comes with built-in functions designed to feed the MetaRegistry with information about the created pools. These functions will not be documented in this section. For more information, please read here.
Contract Source & Deployment
Factories are deployed on the Ethereum Mainnet as well as on Sidechains/L2. Although it might be the case that some pool types (e.g., cryptoswap pools) are not supported there yet. A list of all deployed contracts can be found here.
Warning
The methods below might slightly vary depending on the Factory contract being examined. If there are any abnormalities or important standouts, they will be detailed as accurately as possible within the appropriate section!
The various Curve Factories allow the deployment of pools with virtually any kind of asset combination, whether they are stable or volatile, rebasing or not, etc... Some pool variations (e.g., cryptoswap pool) might not be supported on sidechains/L2s yet.
Factory
Description
Supported Pools
StableSwap
Regular StableSwap
Plain and metapools
StableSwap-NG
Improved StableSwap version
Plain pools with up to eight coins and metapools (more here)
Pool, gauge, or LP token contracts are created according to their implementation contracts set within the Factory. Contracts deployed by newer factories combine both liquidity pool and LP token, whereas for older ones, they are separate contracts.
Earlier factories like the regular stableswap or cryptoswap one use Vyper's built-in create_forwarder_to() function (renamed to create_minimal_proxy_to starting from Vyper version 0.3.4) to deploy liquidity pools, LP tokens, or gauge contracts.
The contracts then need to be initialized, which is done automatically.
Newer factories make use of blueprints (EIP-5202). The contracts are directly created from their corresponding blueprint implementations. This is the most desired and used method for all newly deployed factories.
The fee receiver is set within the Factory and is a uniform address for all the deployed pools through a factory. The address can be changed by the admin of the contract by calling the set_fee_receiver method and setting a new address.
This function is only callable by the admin of the contract.
Function to set a new fee receiver.
Input
Type
Description
_pool
address
This variable has no real use; insert a random address, otherwise the transaction will fail.
_fee_receiver
address
Address of the new fee receiver
Source code
# fee receiver for all poolsfee_receiver:public(address)@externaldefset_fee_receiver(_pool:address,_fee_receiver:address):""" @notice Set fee receiver for all pools @param _pool Address of pool to set fee receiver for. @param _fee_receiver Address that fees are sent to """assertmsg.sender==self.admin# dev: admin onlyself.fee_receiver=_fee_receiver
The admin is the owner of the Factory contract and has the ability to call admin-only functions. Ownership can be transferred by first committing to the transfer of ownership (commit_transfer_ownership), which then needs to be accepted by the future_admin (accept_transfer_ownership).
Most contracts are 'owned' by a proxy, which in turn is owned by the DAO. For some factories, the DAO is directly the owner.
This function is only callable by the admin of the contract.
Function to commit a transfer of ownership. This function sets _addr as the future admin of the contract. These changes need to be applied via accept_transfer_ownership by the future admin itself.
Input
Type
Description
_addr
address
Address of the future admin
Source code
admin:public(address)future_admin:public(address)@externaldefcommit_transfer_ownership(_addr:address):""" @notice Transfer ownership of this contract to `addr` @param _addr Address of the new owner """assertmsg.sender==self.admin# dev: admin onlyself.future_admin=_addr
This function is only callable by the future_admin of the contract.
Function to accept the ownership transfer.
Source code
admin:public(address)future_admin:public(address)@externaldefaccept_transfer_ownership():""" @notice Accept a pending ownership transfer @dev Only callable by the new owner """_admin:address=self.future_adminassertmsg.sender==_admin# dev: future admin onlyself.admin=_adminself.future_admin=empty(address)
Pool, gauge, or LP token contracts are created according to their implementation contracts set within the Factory.
Technical documentation was done separately for each factory, as they partially vary from each other. Please refer to the corresponding section.
Warning
Implementation contracts are upgradable. They can either be replaced, or additional implementation contracts can be added. Therefore, please always make sure to check the most recent ones.