Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set price cap adapters #223

Merged
merged 21 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/20240227_Multi_SetPriceCapAdapters/SetPriceCapAdapters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: "Set Price Cap Adapters"
author: "BGD Labs (@bgdlabs)"
discussions: "https://governance.aave.com/t/bgd-correlated-asset-price-oracle/16133"
snapshot: "https://snapshot.org/#/aave.eth/proposal/0x387f779952a20e850f941111ccf7aa49022ee35274fd219b9759c0ea240b72e1"
---

## Simple Summary

This proposal aims to use correlated-assets price oracle (CAPO) for LSTs and USD-pegged stable coins.
rustboyar marked this conversation as resolved.
Show resolved Hide resolved

## Motivation

LSTs (Liquid Staking Tokens) are highly correlated to an underlying, with an additional growth component on top of it, and sometimes, slashing dynamics. CAPO for this use case adds an upper side protection. Every time the price adapter is queried, it will get the current ratio of the asset/underlying and compared it with a dynamically calculated upper value of that ratio, using the previously defined parameters. If the current ratio is above the ratio cap, the ratio cap is returned. If not, the current ratio is.

In some cases, the relation between an underlying asset and its correlated is direct, without any type of continuous growth expected. For example, this is the case of USD-pegged stable coins, where USD is the underlying and let's say USDC is the correlated asset. For this type of assets we'll apply the price adapter with the fixed price cap.

## Specification

rustboyar marked this conversation as resolved.
Show resolved Hide resolved
- [Capped price adapters implementation](https://github.com/bgd-labs/aave-capo)
- [Risk providers parameters recommendations](https://governance.aave.com/t/chaos-labs-correlated-asset-price-oracle-framework/16605)

| Asset | Growth percent | Snapshot delay |
| ------- | -------------- | -------------- |
| wstETH | 9.68% | 7 days |
| rETH | 9.3% | 7 days |
| sDAI | 10.15% | 7 days |
| cbETH | 8.12% | 7 days |
| MaticX | 10.2% | 14 days |
| stMATIC | 10.45% | 14 days |
| sAVAX | 10.1% | 14 days |
| stEUR | 9.26% | |
rustboyar marked this conversation as resolved.
Show resolved Hide resolved

All stablecoins are capped at 4%.

# Security

- [Audit by Certora](TODO: pase link when available)
- A retrospective test was conducted for the last half year with the parameters provided, which showed that the price was not capped, which is expected
- Inner review at BGD
rustboyar marked this conversation as resolved.
Show resolved Hide resolved

## References

- Payloads: [AaveV3Ethereum](https://github.com/bgd-labs/aave-capo/blob/main/src/contracts/payloads/AaveV3EthereumPayload.sol), [AaveV3Polygon](https://github.com/bgd-labs/aave-capo/blob/main/src/contracts/payloads/AaveV3PolygonPayload.sol), [AaveV3Avalanche](https://github.com/bgd-labs/aave-capo/blob/main/src/contracts/payloads/AaveV3AvalanchePayload.sol), [AaveV3Arbitrum](https://github.com/bgd-labs/aave-capo/blob/main/src/contracts/payloads/AaveV3ArbitrumPayload.sol), [AaveV3Optimism](https://github.com/bgd-labs/aave-capo/blob/main/src/contracts/payloads/AaveV3OptimismPayload.sol), [AaveV3Metis](https://github.com/bgd-labs/aave-capo/blob/main/src/contracts/payloads/AaveV3MetisPayload.sol), [AaveV3Base](https://github.com/bgd-labs/aave-capo/blob/main/src/contracts/payloads/AaveV3BasePayload.sol), [AaveV3Gnosis](https://github.com/bgd-labs/aave-capo/blob/main/src/contracts/payloads/AaveV3GnosisPayload.sol), [AaveV3BNB](https://github.com/bgd-labs/aave-capo/blob/main/src/contracts/payloads/AaveV3BNBPayload.sol)
- Tests:
rustboyar marked this conversation as resolved.
Show resolved Hide resolved

## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {GovV3Helpers, IPayloadsControllerCore, PayloadsControllerUtils} from 'aave-helpers/GovV3Helpers.sol';
import {EthereumScript, PolygonScript, AvalancheScript, OptimismScript, ArbitrumScript, MetisScript, BaseScript, GnosisScript, BNBScript} from 'aave-helpers/ScriptUtils.sol';

library Payloads {
address public constant ETHEREUM = address(0);
address public constant POLYGON = address(1);
address public constant AVALANCHE = address(2);
address public constant OPTIMISM = address(3);
address public constant ARBITRUM = address(4);
address public constant METIS = address(5);
address public constant BASE = address(6);
address public constant GNOSIS = address(7);
address public constant BNB = address(8);
}

/**
* @dev Deploy Ethereum
* deploy-command: make deploy-ledger contract=src/20240206_Multi_SetPriceCapPriceAdapters/SetPriceCapPriceAdapters_20240206.s.sol:DeployEthereum chain=mainnet
* verify-command: npx catapulta-verify -b broadcast/SetPriceCapPriceAdapters_20240206.s.sol/1/run-latest.json
*/
contract DeployEthereum is EthereumScript {
function run() external broadcast {
// compose action
IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](1);
actions[0] = GovV3Helpers.buildAction(Payloads.ETHEREUM);

// register action at payloadsController
GovV3Helpers.createPayload(actions);
}
}

/**
* @dev Deploy Polygon
* deploy-command: make deploy-ledger contract=src/20240206_Multi_SetPriceCapPriceAdapters/SetPriceCapPriceAdapters_20240206.s.sol:DeployPolygon chain=polygon
* verify-command: npx catapulta-verify -b broadcast/SetPriceCapPriceAdapters_20240206.s.sol/137/run-latest.json
*/
contract DeployPolygon is PolygonScript {
function run() external broadcast {
// compose action
IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](1);
actions[0] = GovV3Helpers.buildAction(Payloads.POLYGON);

// register action at payloadsController
GovV3Helpers.createPayload(actions);
}
}

/**
* @dev Deploy Avalanche
* deploy-command: make deploy-ledger contract=src/20240206_Multi_SetPriceCapPriceAdapters/SetPriceCapPriceAdapters_20240206.s.sol:DeployAvalanche chain=avalanche
* verify-command: npx catapulta-verify -b broadcast/SetPriceCapPriceAdapters_20240206.s.sol/43114/run-latest.json
*/
contract DeployAvalanche is AvalancheScript {
function run() external broadcast {
// compose action
IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](1);
actions[0] = GovV3Helpers.buildAction(Payloads.AVALANCHE);

// register action at payloadsController
GovV3Helpers.createPayload(actions);
}
}

/**
* @dev Deploy Optimism
* deploy-command: make deploy-ledger contract=src/20240206_Multi_SetPriceCapPriceAdapters/SetPriceCapPriceAdapters_20240206.s.sol:DeployOptimism chain=optimism
* verify-command: npx catapulta-verify -b broadcast/SetPriceCapPriceAdapters_20240206.s.sol/10/run-latest.json
*/
contract DeployOptimism is OptimismScript {
function run() external broadcast {
// compose action
IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](1);
actions[0] = GovV3Helpers.buildAction(Payloads.OPTIMISM);

// register action at payloadsController
GovV3Helpers.createPayload(actions);
}
}

/**
* @dev Deploy Arbitrum
* deploy-command: make deploy-ledger contract=src/20240206_Multi_SetPriceCapPriceAdapters/SetPriceCapPriceAdapters_20240206.s.sol:DeployArbitrum chain=arbitrum
* verify-command: npx catapulta-verify -b broadcast/SetPriceCapPriceAdapters_20240206.s.sol/42161/run-latest.json
*/
contract DeployArbitrum is ArbitrumScript {
function run() external broadcast {
// compose action
IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](1);
actions[0] = GovV3Helpers.buildAction(Payloads.ARBITRUM);

// register action at payloadsController
GovV3Helpers.createPayload(actions);
}
}

/**
* @dev Deploy Metis
* deploy-command: make deploy-ledger contract=src/20240206_Multi_SetPriceCapPriceAdapters/SetPriceCapPriceAdapters_20240206.s.sol:DeployMetis chain=metis
* verify-command: npx catapulta-verify -b broadcast/SetPriceCapPriceAdapters_20240206.s.sol/1088/run-latest.json
*/
contract DeployMetis is MetisScript {
function run() external broadcast {
// compose action
IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](1);
actions[0] = GovV3Helpers.buildAction(Payloads.METIS);

// register action at payloadsController
GovV3Helpers.createPayload(actions);
}
}

/**
* @dev Deploy Base
* deploy-command: make deploy-ledger contract=src/20240206_Multi_SetPriceCapPriceAdapters/SetPriceCapPriceAdapters_20240206.s.sol:DeployBase chain=base
* verify-command: npx catapulta-verify -b broadcast/SetPriceCapPriceAdapters_20240206.s.sol/8453/run-latest.json
*/
contract DeployBase is BaseScript {
function run() external broadcast {
// compose action
IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](1);
actions[0] = GovV3Helpers.buildAction(Payloads.BASE);

// register action at payloadsController
GovV3Helpers.createPayload(actions);
}
}

/**
* @dev Deploy Gnosis
* deploy-command: make deploy-ledger contract=src/20240206_Multi_SetPriceCapPriceAdapters/SetPriceCapPriceAdapters_20240206.s.sol:DeployGnosis chain=gnosis
* verify-command: npx catapulta-verify -b broadcast/SetPriceCapPriceAdapters_20240206.s.sol/100/run-latest.json
*/
contract DeployGnosis is GnosisScript {
function run() external broadcast {
// compose action
IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](1);
actions[0] = GovV3Helpers.buildAction(Payloads.GNOSIS);

// register action at payloadsController
GovV3Helpers.createPayload(actions);
}
}

/**
* @dev Deploy BNB
* deploy-command: make deploy-ledger contract=src/20240206_Multi_SetPriceCapPriceAdapters/SetPriceCapPriceAdapters_20240206.s.sol:DeployBNB chain=bnb
* verify-command: npx catapulta-verify -b broadcast/SetPriceCapPriceAdapters_20240206.s.sol/56/run-latest.json
*/
contract DeployBNB is BNBScript {
function run() external broadcast {
// compose action
IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](1);
actions[0] = GovV3Helpers.buildAction(Payloads.BNB);

// register action at payloadsController
GovV3Helpers.createPayload(actions);
}
}

/**
* @dev Create Proposal
* command: make deploy-ledger contract=src/20240206_Multi_SetPriceCapPriceAdapters/SetPriceCapPriceAdapters_20240206.s.sol:CreateProposal chain=mainnet
*/
contract CreateProposal is EthereumScript {
function run() external {
// create payloads
PayloadsControllerUtils.Payload[] memory payloads = new PayloadsControllerUtils.Payload[](9);

// compose actions for validation
IPayloadsControllerCore.ExecutionAction[]
memory actionsEthereum = new IPayloadsControllerCore.ExecutionAction[](1);
actionsEthereum[0] = GovV3Helpers.buildAction(Payloads.ETHEREUM);
payloads[0] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum);

IPayloadsControllerCore.ExecutionAction[]
memory actionsPolygon = new IPayloadsControllerCore.ExecutionAction[](1);
actionsPolygon[0] = GovV3Helpers.buildAction(Payloads.POLYGON);
payloads[1] = GovV3Helpers.buildPolygonPayload(vm, actionsPolygon);

IPayloadsControllerCore.ExecutionAction[]
memory actionsAvalanche = new IPayloadsControllerCore.ExecutionAction[](1);
actionsAvalanche[0] = GovV3Helpers.buildAction(Payloads.AVALANCHE);
payloads[2] = GovV3Helpers.buildAvalanchePayload(vm, actionsAvalanche);

IPayloadsControllerCore.ExecutionAction[]
memory actionsOptimism = new IPayloadsControllerCore.ExecutionAction[](1);
actionsOptimism[0] = GovV3Helpers.buildAction(Payloads.OPTIMISM);
payloads[3] = GovV3Helpers.buildOptimismPayload(vm, actionsOptimism);

IPayloadsControllerCore.ExecutionAction[]
memory actionsArbitrum = new IPayloadsControllerCore.ExecutionAction[](1);
actionsArbitrum[0] = GovV3Helpers.buildAction(Payloads.ARBITRUM);
payloads[4] = GovV3Helpers.buildArbitrumPayload(vm, actionsArbitrum);

IPayloadsControllerCore.ExecutionAction[]
memory actionsMetis = new IPayloadsControllerCore.ExecutionAction[](1);
actionsMetis[0] = GovV3Helpers.buildAction(Payloads.METIS);
payloads[5] = GovV3Helpers.buildMetisPayload(vm, actionsMetis);

IPayloadsControllerCore.ExecutionAction[]
memory actionsBase = new IPayloadsControllerCore.ExecutionAction[](1);
actionsBase[0] = GovV3Helpers.buildAction(Payloads.BASE);
payloads[6] = GovV3Helpers.buildBasePayload(vm, actionsBase);

IPayloadsControllerCore.ExecutionAction[]
memory actionsGnosis = new IPayloadsControllerCore.ExecutionAction[](1);
actionsGnosis[0] = GovV3Helpers.buildAction(Payloads.GNOSIS);
payloads[7] = GovV3Helpers.buildGnosisPayload(vm, actionsGnosis);

IPayloadsControllerCore.ExecutionAction[]
memory actionsBNB = new IPayloadsControllerCore.ExecutionAction[](1);
actionsBNB[0] = GovV3Helpers.buildAction(Payloads.BNB);
payloads[8] = GovV3Helpers.buildBNBPayload(vm, actionsBNB);

// create proposal
vm.startBroadcast();
GovV3Helpers.createProposal(
vm,
payloads,
GovV3Helpers.ipfsHashFile(vm, 'src/20240206_Multi_SetPriceCapAdapters/SetPriceCapAdapters.md')
);
}
}
14 changes: 14 additions & 0 deletions src/20240227_Multi_SetPriceCapAdapters/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {ConfigFile} from '../../generator/types';
export const config: ConfigFile = {
rootOptions: {
pools: [],
title: 'Set Price Cap Adapters',
shortName: 'SetPriceCapAdapters',
date: '20240206',
author: 'BGD Labs (@bgdlabs)',
discussion: 'https://governance.aave.com/t/bgd-correlated-asset-price-oracle/16133',
snapshot:
'https://snapshot.org/#/aave.eth/proposal/0x387f779952a20e850f941111ccf7aa49022ee35274fd219b9759c0ea240b72e1',
},
poolOptions: {},
};
Loading