good morning!!!!

Skip to content
Snippets Groups Projects
Commit f00f1019 authored by Jake Barber's avatar Jake Barber
Browse files

docs update

parent 1a84b312
No related branches found
No related tags found
No related merge requests found
# Oracle System for BPTs as Collateral
## Original Oracle System
By far the biggest hurdle to this project is coming up with a robust and accurate oracle system to price BPTs as collateral.
The naïve approach to pricing an LP token is to simply gather the total asset values that back the LP (total balance of each asset multiplied by a known price) and divide by the total supply of the LP. So LTV / Total Supply.
We can call this price the naïve price, and if manipulation were not a factor, this would be the ideal price to use when deriving a value for BPTs as collateral on Interest Protocol.
If priced this way, a flash loan attack could manipulate the underlying asset balances in a significant enough way to alter the price of the LP token for a single block, allowing for malicious actions such as inflating the ‘price’ of the BPT, so a borrower on IP can borrow more than they should against their BPT collateral. If this attack can alter the balances enough to inflate the BPT price to a greater extent than the LTV, an attacker could walk away with a profit in borrowed USDi, leaving some bad debt behind.
A solution to price BPTs from Weighted Pools was already developed in principle by [Revest Finance](https://github.com/Revest-Finance/ResonateContracts/blob/public/hardhat/contracts/oracles/adapters/balancer/BalancerV2WeightedPoolPriceOracle.sol) as described in this [article](https://revestfinance.medium.com/dev-blog-on-the-derivation-of-a-safe-price-formula-for-balancer-pool-tokens-33e8993455d0). The implementation for weighted pools works based on this formula and has been tested to be accurate.
Importantly, this solution does not even ask the [Balancer Vault](https://etherscan.io/address/0xba12222222228d8ba445958a75a0704d566bf2c8) what the pool balances are, yet is still able to accurately calculate the LTV of the pool, and so should be safe and resistant to manipulation.
The solution to solving this problem for StablePools / MetaStablePools unfortunately is less straightforward.
StablePools differ from MetaStablePools in that they are made up of two assets that are often similar in value, rather than two otherwise related assets. For example, the stable pool [B-auraBAL-STABLE](https://etherscan.io/address/0x3dd0843a028c86e0b760b1a76929d1c5ef93a2dd#readContract) is a pool between AuraBal and the BPT [B-80BAL-20WETH](https://etherscan.io/address/0x5c6Ee304399DBdB9C8Ef030aB642B10820DB8F56#readContract), which is the unstaked version of veBal. Therefore, these two should be roughly equal in value, as they represent the same underlying asset and functionality.
The solution recommended by Chainlink via this [article](https://blog.chain.link/using-chainlink-oracles-to-securely-utilize-curve-lp-pools/) is to use a method that we can call MinSafePrice. This method is supposed to calculate a safe lower bound for the true price of the BPT. Protocols can then use this MinSafePrice as the market price for the BPTs, resulting in a safe (if slightly undervalued) price for the collateral.
However, in testing, the results of this method are often slightly higher than the expected naïve price, which doesn’t make much sense if this price is supposed to be a lower bound.
This behavior can further be confirmed by an audit of [Sturdy Finance](https://sturdy.finance/) which utilizes this type of oracle for StablePools / MetaStablePools. See [QSP-4 of their audit report](https://certificate.quantstamp.com/full/sturdy-aura-integration-and-leverage.pdf).
After trial and error with a number of other possible solutions, the best solution currently tested is to utilize the [outGivenIn](https://github.com/balancer/balancer-v2-monorepo/blob/93af2fda1eefe1b7d103e6c54ce159951ff001fc/pkg/pool-stable/contracts/StableMath.sol#L124) logic to determine if manipulation has taken place.
In essence, we can know the market exchange rate of the two assets in the pool if we can price them with external oracles. We can then compare this to the price rate computed by the pool.
This pool price rate is of course subject to manipulation, but we can detect this manipulation by comparing the result to the true market exchange rate.
In this way, we can confirm that manipulation has not taken place, and therefore utilize the naïve price.
## Technical Writeup
More info on this can be found in this [full technical writeup](https://docs.google.com/document/d/1u4dju8zORKWp3mEoCcEFgDvt90ro0tu17GOOLH2tHxY/edit) of the oracle systems.
# Interest Protocol allows Balancer LP tokens (BPT) to be utilized as collateral
## Overview
Balancer LP tokens are yield-bearing tokens that accrue yield to the owners from fees and rewards.
## Description
Interest Protocol and GFX Labs have worked to implement measures to add Balancer LP tokens as collateral, and to stake these for Aura Liquidity Provider reward tokens while in the Interest Protocol vaults, giving borrowers the ability to stake these assets where applicable, as well as the ability to claim any rewards for staking.
This proposal will require an upgrade to the existing VotingVaultController, to allow it to track the new vault type as well as registered BPTs.
The first asset to be proposed for listing is [B-stETH-STABLE](https://app.balancer.fi/#/ethereum/pool/0x32296969ef14eb0c6d29669c550d4a0449130230000200000000000000000080). This is a MetaStablePool on the Balancer protocol. MetaStablePools are made up of two assets that are tied together in some way, where one is generally pegged to the other. In this case, the assets are wstETH and wETH. MetaStablePools like this one incorporate a [rate provider contract](https://etherscan.io/address/0x72D07D7DcA67b8A406aD1Ec34ce969c90bFEE768#readContract) to determine the exchange rate between the two assets.
Like most other assets on Interest Protocol, the collateral will be wrapped by a Cap contract in order to limit the total supply allowed on the protocol, thus mitigating liquidity risk. In this case it will be wrapped by a new [CappedBptToken Contract](https://gfx.cafe/ip/contracts/-/blob/master/contracts/lending/wrapper/CappedBptToken.sol).
While the goal is to end up with a staked [Aura Reward Token](https://etherscan.io/address/0xe4683Fe8F53da14cA5DAc4251EaDFb3aa614d528) in the Interest Protocol vault as collateral, these tokens are not able to be transferred, so users must deposit regular Balancer LPs (BPTs) such as B-stETH-STABLE, and these must then be staked on Aura in exchange for the reward token. This staking is, of course, done in an automated way upon deposit into a user’s vault.
The reasoning for this is because if we look at the [holders of B-stETH-STABLE](https://etherscan.io/token/0x32296969Ef14EB0c6d29669C550D4a0449130230#balances) on Etherscan, we can see that the overwhelming majority of these BPTs are held by the [Gauge Contract](https://etherscan.io/address/0xcD4722B7c24C29e0413BDCd9e51404B4539D14aE). This is because in order to maximize rewards for your BPT, it should be staked on the corresponding gauge contract, in exchange for these Gauge Tokens.
However, if we further look at the [holders of the gauge token](https://etherscan.io/token/0xcD4722B7c24C29e0413BDCd9e51404B4539D14aE#balances), we can again see that the overwhelming majority are held by the [Aura Voter Proxy](https://etherscan.io/address/0xaF52695E1bB01A16D33D7194C28C42b10e0Dbec2). This is because one can further increase rewards by staking through the Aura Finance infrastructure, which stakes deposited BPTs for Gauge Tokens, then consolidates the voting power into the single Aura Voter Proxy contract.
So we can see that the majority of stakers are providing liquidity through the Aura Finance infrastructure, as the [holders of the Aura Reward Token](https://etherscan.io/token/0xe4683Fe8F53da14cA5DAc4251EaDFb3aa614d528#balances) have a good distribution. Unfortunately, the Aura contracts do not allow the deposit of Gauge tokens for staking, only the underlying BPT, so this is why on Interest Protocol the listed asset will be the BPT, rather than the Gauge Token or Aura Reward Token.
Because BPTs, Gauge Tokens, and Aura Reward Tokens are all issued 1:1 with each other, our oracle can price all of them at the same value.
Staking is done via the [Aura Booster Contract](https://etherscan.io/address/0xA57b8d98dAE62B26Ec3bcC4a365338157060B234), which handles all of the staking, and delivers the Aura Reward Token in exchange for the underlying BPT. The logic to handle this is on the new version 3 Vault on Interest Protocol, the [VaultBPT](https://gfx.cafe/ip/contracts/-/blob/master/contracts/lending/vault/VaultBPT.sol).
## Staking in Detail
Staking BPTs while using them as collateral presents some challenges.
The first of which is that if the Aura Reward Token is not transferable, how do we liquidate a position if needed?
In order to achieve this, the transfer function of the VaultBPT is overridden to automatically unstake any staked BPTs therein. As the transfer function should only be called upon liquidation or withdrawal, this results in a smooth transition of staked illiquid Aura Reward Tokens to transferable BPTs.
In the case of a partial liquidation, all of the staked Aura Reward Tokens will be unstaked, but not all of the underlying BPTs will be transferred out from the Vault, so the vault owner will need to stake again in order to maximize the rewards.
Another challenge is that the staking of BPTs into Aura Reward Tokens happens differently than staking [AuraBal](https://etherscan.io/token/0x616e8bfa43f920657b3497dbf40d6b1a02d4608d), and we wanted the new vault type to be able to handle both.
AuraBal is similar to BPTs in the sense that it can be staked for Aura Reward Tokens, however rather than being an LP for the Balancer Protocol, AuraBal represents liquid [veBal](https://etherscan.io/token/0xC128a9954e6c874eA3d62ce62B468bA073093F25), (Vote Escrowed Balancer BPT). This token is not transferable, and represents the voting power for the Balancer protocol. More about veBal can be read about in the [Balancer Docs](https://docs.balancer.fi/concepts/governance/veBAL/), and more about AuraBal can be found in the [Aura Docs](https://docs.aura.finance/aura/what-is-aura).
Essentially, AuraBal can be staked by simply calling stakeAll() on its corresponding Aura Reward Token, whereas regular BPTs must first be staked into Gauge Tokens which must be sent to the Aura Voter Proxy contract in the correct way. Therefore, staking of normal BPTs happens via the Aura Booster Contract.
As part of the asset listing process, BPTs are associated with their corresponding Aura Reward Token so that staking can take place.
## Claiming of Rewards
Rewards can be claimed regardless of liability, including support for extra rewards (supported by some Aura Reward Tokens).
For example, in the case of the token being listed, B-stETH-STABLE, standard rewards are paid in [BAL](https://etherscan.io/token/0xba100000625a3754423978a60c9317c58a424e3D) tokens, and extra rewards are currently configured to be paid in [LDO](https://etherscan.io/address/0x5A98FcBEA516Cf06857215779Fd812CA3beF1B32).
Claiming of extra rewards is an optional bool argument when calling claimAuraLpRewards() on the VaultBPT contract. Claiming extra rewards is gas intensive and so should not be done if there are no extra rewards to be claimed.
Rewards are always sent to the vault minter, and as such claiming rewards is not a permissioned function.
Claiming of rewards has the possibility of doing a solvency check if needed. While this consumes a lot of extra gas, it is needed because if any of the rewards or extra rewards tokens happen to be a BPT registered as collateral, then claiming rewards would transfer out all of the collateral without regard for any liability that may exist on the vault.
The solvency check only happens if the rewards or extra rewards tokens happen to be a BPT registered as collateral, otherwise, the solvency check is skipped, saving about 450k gas.
# Interest Protocol allows Uniswap V3 positions to be used as collateral
## Overview
Uniswap V3 positions are made up of the underlying assets of the respective pool, and may be valued as such.
In order to fully understand the pricing of Uniswap v3 positions, it is important to first understand the basics of how concentrated liquidity works in Uniswap V3.
The [Uniswap V3 Development Book](https://uniswapv3book.com/) is a good resource for this.
### Implementations
[VaultNft](https://gfx.cafe/ip/contracts/-/blob/master/contracts/lending/vault/VaultNft.sol)
[NftVaultController](https://gfx.cafe/ip/contracts/-/blob/master/contracts/lending/controller/NftVaultController.sol)
[V3PositionValuator](https://gfx.cafe/ip/contracts/-/blob/master/contracts/oracle/External/V3PositionValuator.sol)
[Univ3CollateralToken](https://gfx.cafe/ip/contracts/-/blob/master/contracts/lending/wrapper/Univ3CollateralToken.sol)
## Detailed Description
Pricing for the positions is determined by a single valuator contract, V3PositionManager. The Position Valuator is an upgradeable proxy which will be owned by Interest Protocol governance. This contract independently calculates the current sqrt price (using external oracles for the two underlying tokens), and then calculates the amounts for the underlying tokens of the position, were they to be withdrawn immediately. Based on these token amounts, we can determine the value of the position
In short, a position is represented by a single non-fungible token ([NFT](https://eips.ethereum.org/EIPS/eip-721)), which contains data describing the position. From this data, the upper and lower bounds of the position (tickUpper/tickLower) as well as the liquidity are used to determine the price.
Additionally, the token0, token1, and fee from the position are used to calculate the pool address, which is needed in order to confirm registration of the pool, as well as to determine the correct external oracles to use to price the underlying asset of the pool. The Position Valuator keeps track of which pools are registered for use on Interest Protocol.
Positions are deposited into the new Univ3CollateralToken contract, which wraps the position into a modified ERC-20 type token. Univ3CollateralToken is a new upgradeable proxy contract owned by Interest Protocol governance, and effectively wraps the Uniswap V3 position as an ERC-20 token.
This token is then transferred to the standard vault (v1), while the actual position is sent to a new vault type, VaultNft (v3). All current and future pools listed as collateral will be using this same contract deployment, so no additional deployments are needed to list more pools, other than any additional external oracles, though most of these external oracles are likely already in use on IP for currently listed assets.
This wrapper on the surface appears to work generally the same way as any standard ERC-20, but underneath there are a number of custom changes.
The key difference lies in the balanceOf function of the Univ3CollateralToken. This function requires that the address passed be a standard vault address, and when called returns the actual value (in USDi terms) of the positions held by the VaultNft(v3) with that vault ID.
Positions are associated with a minter’s wallet address in an array. Multiple positions are allowed, and are stored in a dynamic array, which can be read by calling depositedPositions(address minter).
<u>__Partial liquidations are not allowed, in the case of liquidation, the liquidator will receive all positions held by the vault.__ </u>
Additionally, if a vault contains any standard or capped assets in addition to any Uniswap V3 Positions, those assets must be completely liquidated __before__ liquidation of the Uniswap position can occur.
Partial withdrawals are allowed. For the “amount” argument, pass the index of the position to withdraw with respect to where it is stored in the dynamic array. Mutation of the list is handled such that if a middle index is withdrawn, its index in the array will be replaced with the final index, and the new array’s length will be reduced by 1.
If the “amount” argument is greater than the number of positions held by the vault, then all positions will be withdrawn. Liquidations are hard coded to pass the max possible uint256 for the “amount”.
VaultNft minters can collect fees generated by their positions at any time, these fees are not included in the value of the position.
The current implementation does not allow for a cap, so pools should be listed conservatively. Because the price is treated as equivalent to the balance in our wrapper, the total supply is effectively dynamic and moves with the price. Therefore, it is not feasible to cap the total supply of the wrapper as is done with other capped assets.
As such, there is no mint event when depositing to the wrapper contract, and totalSupply is never changed, and so is always 0.
\ No newline at end of file
# How to Make a Cross-Chain Proposal intended for the Interest Protocol Deployment on Optimism
This guide builds off off [How To Make A Proposal](./HowToMakeAProposal.md), so the basics of how to make proposals and IP governance should be understood prior to this guide.
## Technical Cross Chain Governance Details
The following describes the general process for which mainnet IP governance will control the Optimisim deployment.
[Layer 1 Cross Chain Messenger](https://etherscan.io/address/0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1#code)
This is the official contract for sending data from Mainnet to Optimism. Upon execution of a cross-chain proposal to Optimism, IP governance will call `sendMessage` on this contract, initiating the passing of data to Optimism.
[Cross Chain Account](https://optimistic.etherscan.io/address/0x48fa7528bFD6164DdF09dF0Ed22451cF59c84130)
This contract receives the data sent from Mainnet, and forwards it to the Interest Protocol contracts. As such, this contract has ownership of all Interest Protocol contracts on Optimism.
All of the data to make these transactions happen must be carefully nested in the proposal on Mainnet. An example script to do this can be found [here](https://gfx.cafe/ip/contracts/-/blob/master/scripts/proposals/SNX_OP/propose.ts)
So for example, if we are to set the new oracle on the [Oracle Master](https://optimistic.etherscan.io/address/0xBdCF0bb40eb8642f907133bDB5Fcc681D81f0651), we need to first package the data to do this, which we can call addOracleData.
Then we take this data, and use it as the "bytes" argument when we call call to forward(address,bytes) on the [Cross Chain Account](https://optimistic.etherscan.io/address/0x48fa7528bFD6164DdF09dF0Ed22451cF59c84130) on Optimism. This function takes two arguments, first the Oracle Master address on Optimism, and second, our addOracleData (bytes).
We take our addOracleForwardData, and pass it as the _message (bytes) when we call sendMessage(address,bytes,uint32) on the [Layer 1 Cross Chain Messenger](https://etherscan.io/address/0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1#code)
Assuming the Oracle Master on Optimism has its owner set to the [Cross Chain Account](https://optimistic.etherscan.io/address/0x48fa7528bFD6164DdF09dF0Ed22451cF59c84130), this should set the new relay as expected.
\ No newline at end of file
# CappedBptToken
## Overview
A Capped BPT Token is a wrapper for an underlying BPT asset that can be listed as collateral on the protocol, while governance can limit the total supply of the Capped Collateral Token. The Capped Collateral contract does not hold any assets. The user's sub-vault (bpt vault) holds the underlying tokens. By controlling the tokens in the sub-vaults rather than the token contract, token holders can retain the ability to vote and/or earn rewards with their underlying tokens.
## Initialize
```
function initialize(
string memory name_,
string memory symbol_,
address underlying_,
address vaultController_,
address votingVaultController_
) public initializer {
__Ownable_init();
__ERC20_init(name_, symbol_);
_underlying = ERC20Upgradeable(underlying_);
_vaultController = IVaultController(vaultController_);
_votingVaultController = VotingVaultController(votingVaultController_);
locked = false;
}
```
## Functions
* function decimals() public
* returns 18 (hardcoded at deployment)
* function getCap() public
* returns _cap (uint 256 in 18 terms)
* function setCap(uint256 cap_) external onlyOwner
* governance can set the cap in 18 terms
* function checkCap(uint256 amount_) internal view
* each deposit checks to make sure the deposit won't exceed the cap
* function deposit(uint256 amount, uint96 vaultId, bool stake) public nonReentrant
* transfers the underlying token to the sub-vault (bpt vault) and transfers the capped token to the parent vault
* `stake` should generally be true, as this will complete the steps to stake the underlying BPT for maximum rewards
* function transfer(address recipient, uint256 amount) public
* supports the withdraw of the capped token for the underlying token when the vault owner calls withdraw on the parent vault
* function transferFrom(address, address, uint256)
* explicitly overrides from being used
* function renounceOwnership() public virtual onlyOwner
* leaves the contract without owner
* function transferOwnership(address newOwner) public virtual onlyOwner
* transfers ownership of the contract to a new account
* function balanceOf(address account) public
* returns the balance of an address
* function name() external view
* returns string
* function symbol() external view
* returns string
* function totalSupply() public
* total supply of capped tokens
# Capped Collateral Token # Capped Collateral Token
## Overview ## Overview
A Capped Collateral Token is a wrapper for an underlying asset that can be listed as collateral on the protocol, while governance can control the total supply of the Capped Collateral Token. The Capped Collateral contract does not hold any assets. The user's sub-vault (voting vault) holds the underlying tokens. By controlling the tokens in the sub-vaults rather than the token contract, governance token holders can retain voting power while being utilized as collateral assets. A Capped Collateral Token is a wrapper for an underlying asset that can be listed as collateral on the protocol, while governance can limit the total supply of the Capped Collateral Token. The Capped Collateral contract does not hold any assets. The user's sub-vault (voting vault) holds the underlying tokens. By controlling the tokens in the sub-vaults rather than the token contract, governance token holders can retain voting power while being utilized as collateral assets.
## Initialize ## Initialize
``` ```
......
# NftVaultController
## Overview
The Nft Vault Controller manages the minting of Nft sub-vaults, registration of the UniV3CollateralToken, and supports withdrawing the underlying Nfts from vaults. The contract is upgradable and owned by Interest Protocol governance.
## Initialize
```
function initialize(address vaultController_) public initializer {
__Ownable_init();
_vaultController = IVaultController(vaultController_);
}
```
## Functions
## Functions
* function registerUnderlying(address underlying_address, address capped_token) external onlyOwner
* governance can register the UniV3CollateralToken by calling the register function here and on the main controller
* function retrieveUnderlying(uint256 amount, address voting_vault, address target) public
* supports position withdraws when the main vault calls the transfer function
* function mintVault(uint96 id) public
* Anyone can mint a sub-vault for a parent vault but only the parent has control
* function NftVaultId(address nft_vault_address) public
* returns nft vault ID
* function vaultId(address vault_address) public
* returns vault ID
* function NftVaultAddress(uint96 vault_id) public
* returns nft vault address
# Univ3CollateralToken
## Overview
Univ3CollateralToken is a wrapped Uniswap V3 position, allowing Interest Protocol use it as collateral.
There should generally exist only one of these on a given network, as the underlying will always be the Uniswap V3 NonFungiblePositionManager, regardless of the pool the position represents.
## Initialize
```
function initialize(
string memory name_,
string memory symbol_,
address underlying_,
address vaultController_,
address nftVaultController_,
address positionValuator_
) public initializer {
__Ownable_init();
__ERC20_init(name_, symbol_);
_underlying = INonfungiblePositionManager(underlying_);
_positionValuator = V3PositionValuator(positionValuator_);
_vaultController = IVaultController(vaultController_);
_nftVaultController = NftVaultController(nftVaultController_);
locked = false;
}
```
## Functions
* function deposit(uint256 amount, uint96 vaultId) public
* transfers the underlying token to the sub-vault (nft vault) and transfers the wrapped token to the parent vault
* function transfer(address recipient, uint256 amount) public
* supports the withdraw of the wrapped token for the underlying token when the vault owner calls withdraw on the parent vault
* function transferFrom(address, address, uint256)
* explicitly overrides from being used
* function renounceOwnership() public virtual onlyOwner
* leaves the contract without owner
* function transferOwnership(address newOwner) public virtual onlyOwner
* transfers ownership of the contract to a new account
* function balanceOf(address account) public
* returns the balance of an address
* function name() external view
* returns string
* function symbol() external view
* returns string
* function totalSupply() public
* total supply of wrapped tokens
# V3PositionValuator
## Overview
Determines the value of a Uniswap V3 Position, then assigns that value to the `balanceOf()` of a given vaults UniV3CollateralToken balance.
## Initialize
```
function initialize(INonfungiblePositionManager _nfpManager, address _factoryV3) public initializer {
__Ownable_init();
nfpManager = _nfpManager;
FACTORY_V3 = _factoryV3;
}
```
## Functions
## Functions
* function currentValue() external pure override returns (uint256)
* hard coded to return 1e18 to satisfy IOracleRelay interface.
* function getValue(uint256 tokenId) external view returns (uint256)
* returns the value of a given `tokenId` in USDI terms (1e18)
* function verifyPool(uint256 tokenId) public view returns (VerifyData memory)
* determine the pool has been registered, and if so, return the data associated with the given position id `tokenId`
* function registerPool(IUniV3Pool pool, IOracleRelay _token0Oracle, IOracleRelay _token1Oracle) external onlyOwner
* allows governance to register new pools, oracles are needed for each underlying asset
\ No newline at end of file
# Contract Addresses # Contract Addresses
The protocol is deployed on Ethereum Mainnet. The protocol is deployed on Ethereum Mainnet.
### Token Sale ### Governance
* SlowRoll: 0xFbD3060Fe1Ed10c34E236Cee837d82F019cF1D1d * Interest Protocol Token (IPT): 0xd909c5862cdb164adb949d92622082f0092efc3d
* Governor: 0x266d1020a84b9e8b0ed320831838152075f8c4ca
### Core ### Core
* ProxyAdmin: 0x3D9d8c08dC16Aa104b5B24aBDd1aD857e2c0D8C5 * ProxyAdmin: 0x3D9d8c08dC16Aa104b5B24aBDd1aD857e2c0D8C5
...@@ -11,11 +12,12 @@ The protocol is deployed on Ethereum Mainnet. ...@@ -11,11 +12,12 @@ The protocol is deployed on Ethereum Mainnet.
* CurveMaster: 0x0029abd74B7B32e6a82Bf9f62CB9Dd4Bf8e39aAf * CurveMaster: 0x0029abd74B7B32e6a82Bf9f62CB9Dd4Bf8e39aAf
* ThreeLines: 0x482855c43a0869D93C5cA6d9dc9EDdF3DAE031Ea * ThreeLines: 0x482855c43a0869D93C5cA6d9dc9EDdF3DAE031Ea
* OracleMaster: 0xf4818813045E954f5Dc55a40c9B60Def0ba3D477 * OracleMaster: 0xf4818813045E954f5Dc55a40c9B60Def0ba3D477
### Cap Token Infastructure
* VotingVaultController: 0xae49ddca05fe891c6a5492ed52d739ec1328cbe2 * VotingVaultController: 0xae49ddca05fe891c6a5492ed52d739ec1328cbe2
* Capped Token Implementation: 0x9F86bf2C380d3C63177e6104320Fd3D1DcAE88DA
* CappedERC4626Implementation: "0x09fD32C702117BB1dEaA2dD43e2bc8a63A831c7A"
### Governance
* Interest Protocol Token (IPT): 0xd909c5862cdb164adb949d92622082f0092efc3d
* Governor: 0x266d1020a84b9e8b0ed320831838152075f8c4ca
### wETH Oracle ### wETH Oracle
* AnchoredViewRelay: 0x65dA327b1740D00fF7B366a4fd8F33830a2f03A2 * AnchoredViewRelay: 0x65dA327b1740D00fF7B366a4fd8F33830a2f03A2
...@@ -104,7 +106,7 @@ The protocol is deployed on Ethereum Mainnet. ...@@ -104,7 +106,7 @@ The protocol is deployed on Ethereum Mainnet.
* cbETH (capped): 0x99bd1f28a5A7feCbE39a53463a916794Be798FC3 * cbETH (capped): 0x99bd1f28a5A7feCbE39a53463a916794Be798FC3
* ZRX (capped): 0xDf623240ec300fD9e2B7780B34dC2F417c0Ab6D2 * ZRX (capped): 0xDf623240ec300fD9e2B7780B34dC2F417c0Ab6D2
## Polygon Mainnet ## Polygon Mainnet (legacy testing deployments)
* USDC_UNI_CL: 0xdf0fb4e4f928d2dcb76f438575fdd8682386e13c * USDC_UNI_CL: 0xdf0fb4e4f928d2dcb76f438575fdd8682386e13c
* USDC_ETH_CL: 0xf9680d99d6c9589e2a93a78a04a279e509205945 * USDC_ETH_CL: 0xf9680d99d6c9589e2a93a78a04a279e509205945
* USDC_WBTC_CL: 0xDE31F8bFBD8c84b5360CFACCa3539B938dd78ae6 * USDC_WBTC_CL: 0xDE31F8bFBD8c84b5360CFACCa3539B938dd78ae6
......
# Contract Addresses
The protocol is deployed on Optimism Mainnet.
### Governance
* Interest Protocol Token (IPT)(Bridged): 0x4ea5eC30487132328616dBa55E46346CA840B685
* optimismMessenger: 0x48fa7528bFD6164DdF09dF0Ed22451cF59c84130
### Core
* VaultController: 0x05498574BD0Fa99eeCB01e1241661E7eE58F8a85
* Oracle: 0xBdCF0bb40eb8642f907133bDB5Fcc681D81f0651
* USDI: 0x889be273BE5F75a177f9a1D00d84D607d75fB4e1
* ProxyAdmin: 0x2dB08783F13c4225A1963b2437f0D459a5BCB4D8
* Curve: 0xC3A17DC6b70cD58f8aE49Fb969CCA5A57cf84A73
* ThreeLines: 0x7C53378987F6e82050b1244B4d836f785147544b
### Capped Token Infastructure
* VotingVaultController: 0x9C3b60A1ad08740fCD842351ff0960C1Ee3FeA52
* Capped Token Implementation: 0x54fE0D5dA2C787a93f2Dcb4d25E202C4e44e4458
* Capped Non-Standard Implementation (Decimals != 18): 0x227bABe533fa9a1085f5261210E0B7137E44437B
### Uniswap V3 Position Infastructure
* Univ3CollateralToken: 0x7131FF92a3604966d7D96CCc9d596F7e9435195c
* Univ3CollateralToken Implementation: 0x5676e28f594A919F018e4888e43B432870b1856C
* NftControllerImplementation: "0x68338eC08c8bA70230F8621effCb89b2BA45e80F"
* NftController: "0xd5832070A81d607E8932B524f507B47117564CD3"
* PositionValuatorImplementation: "0x5676e28f594A919F018e4888e43B432870b1856C"
* V3PositionValuator: "0x5c69C9551E2fE670eDC82EC0288843c1956eE644"
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment