Skip to content

Commit

Permalink
chore: init aip
Browse files Browse the repository at this point in the history
  • Loading branch information
DhairyaSethi committed Dec 9, 2024
1 parent 82dfded commit c64c0c1
Show file tree
Hide file tree
Showing 8 changed files with 379 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol';
/**
* @title GHO CCIP 1.5.1 Upgrade
* @author Aave Labs
* - Snapshot: TODO
* - Discussion: TODO
*/
contract AaveV3Arbitrum_GHOCCIP151Upgrade_20241209 is IProposalGenericExecutor {
function execute() external {
// custom code goes here
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol';

import 'forge-std/Test.sol';
import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol';
import {AaveV3Arbitrum_GHOCCIP151Upgrade_20241209} from './AaveV3Arbitrum_GHOCCIP151Upgrade_20241209.sol';

/**
* @dev Test for AaveV3Arbitrum_GHOCCIP151Upgrade_20241209
* command: FOUNDRY_PROFILE=arbitrum forge test --match-path=src/20241209_Multi_GHOCCIP151Upgrade/AaveV3Arbitrum_GHOCCIP151Upgrade_20241209.t.sol -vv
*/
contract AaveV3Arbitrum_GHOCCIP151Upgrade_20241209_Test is ProtocolV3TestBase {
AaveV3Arbitrum_GHOCCIP151Upgrade_20241209 internal proposal;

function setUp() public {
vm.createSelectFork(vm.rpcUrl('arbitrum'), 283036001);
proposal = new AaveV3Arbitrum_GHOCCIP151Upgrade_20241209();
}

/**
* @dev executes the generic test suite including e2e and config snapshots
*/
function test_defaultProposalExecution() public {
defaultTest(
'AaveV3Arbitrum_GHOCCIP151Upgrade_20241209',
AaveV3Arbitrum.POOL,
address(proposal)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol';
/**
* @title GHO CCIP 1.5.1 Upgrade
* @author Aave Labs
* - Snapshot: TODO
* - Discussion: TODO
*/
contract AaveV3Ethereum_GHOCCIP151Upgrade_20241209 is IProposalGenericExecutor {
uint64 internal constant ARB_CHAIN_SELECTOR = 4949039107694359620;

function execute() external {
// custom code goes here
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol';

import 'forge-std/Test.sol';
import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol';
import {AaveV3Ethereum_GHOCCIP151Upgrade_20241209} from './AaveV3Ethereum_GHOCCIP151Upgrade_20241209.sol';

/**
* @dev Test for AaveV3Ethereum_GHOCCIP151Upgrade_20241209
* command: FOUNDRY_PROFILE=mainnet forge test --match-path=src/20241209_Multi_GHOCCIP151Upgrade/AaveV3Ethereum_GHOCCIP151Upgrade_20241209.t.sol -vv
*/
contract AaveV3Ethereum_GHOCCIP151Upgrade_20241209_Test is ProtocolV3TestBase {
AaveV3Ethereum_GHOCCIP151Upgrade_20241209 internal proposal;

function setUp() public {
vm.createSelectFork(vm.rpcUrl('mainnet'), 21366260);
proposal = new AaveV3Ethereum_GHOCCIP151Upgrade_20241209();
}

/**
* @dev executes the generic test suite including e2e and config snapshots
*/
function test_defaultProposalExecution() public {
defaultTest(
'AaveV3Ethereum_GHOCCIP151Upgrade_20241209',
AaveV3Ethereum.POOL,
address(proposal)
);
}
}
22 changes: 22 additions & 0 deletions src/20241209_Multi_GHOCCIP151Upgrade/GHOCCIP151Upgrade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: "GHO CCIP 1.5.1 Upgrade"
author: "Aave Labs"
discussions: ""
---

## Simple Summary

## Motivation

## Specification

## References

- Implementation: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241209_Multi_GHOCCIP151Upgrade/AaveV3Ethereum_GHOCCIP151Upgrade_20241209.sol), [AaveV3Arbitrum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241209_Multi_GHOCCIP151Upgrade/AaveV3Arbitrum_GHOCCIP151Upgrade_20241209.sol)
- Tests: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241209_Multi_GHOCCIP151Upgrade/AaveV3Ethereum_GHOCCIP151Upgrade_20241209.t.sol), [AaveV3Arbitrum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241209_Multi_GHOCCIP151Upgrade/AaveV3Arbitrum_GHOCCIP151Upgrade_20241209.t.sol)
- [Snapshot](TODO)
- [Discussion](TODO)

## 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,87 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {GovV3Helpers, IPayloadsControllerCore, PayloadsControllerUtils} from 'aave-helpers/src/GovV3Helpers.sol';
import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol';
import {EthereumScript, ArbitrumScript} from 'solidity-utils/contracts/utils/ScriptUtils.sol';
import {AaveV3Ethereum_GHOCCIP151Upgrade_20241209} from './AaveV3Ethereum_GHOCCIP151Upgrade_20241209.sol';
import {AaveV3Arbitrum_GHOCCIP151Upgrade_20241209} from './AaveV3Arbitrum_GHOCCIP151Upgrade_20241209.sol';

/**
* @dev Deploy Ethereum
* deploy-command: make deploy-ledger contract=src/20241209_Multi_GHOCCIP151Upgrade/GHOCCIP151Upgrade_20241209.s.sol:DeployEthereum chain=mainnet
* verify-command: FOUNDRY_PROFILE=mainnet npx catapulta-verify -b broadcast/GHOCCIP151Upgrade_20241209.s.sol/1/run-latest.json
*/
contract DeployEthereum is EthereumScript {
function run() external broadcast {
// deploy payloads
address payload0 = GovV3Helpers.deployDeterministic(
type(AaveV3Ethereum_GHOCCIP151Upgrade_20241209).creationCode
);

// compose action
IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](1);
actions[0] = GovV3Helpers.buildAction(payload0);

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

/**
* @dev Deploy Arbitrum
* deploy-command: make deploy-ledger contract=src/20241209_Multi_GHOCCIP151Upgrade/GHOCCIP151Upgrade_20241209.s.sol:DeployArbitrum chain=arbitrum
* verify-command: FOUNDRY_PROFILE=arbitrum npx catapulta-verify -b broadcast/GHOCCIP151Upgrade_20241209.s.sol/42161/run-latest.json
*/
contract DeployArbitrum is ArbitrumScript {
function run() external broadcast {
// deploy payloads
address payload0 = GovV3Helpers.deployDeterministic(
type(AaveV3Arbitrum_GHOCCIP151Upgrade_20241209).creationCode
);

// compose action
IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](1);
actions[0] = GovV3Helpers.buildAction(payload0);

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

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

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

IPayloadsControllerCore.ExecutionAction[]
memory actionsArbitrum = new IPayloadsControllerCore.ExecutionAction[](1);
actionsArbitrum[0] = GovV3Helpers.buildAction(
type(AaveV3Arbitrum_GHOCCIP151Upgrade_20241209).creationCode
);
payloads[1] = GovV3Helpers.buildArbitrumPayload(vm, actionsArbitrum);

// create proposal
vm.startBroadcast();
GovV3Helpers.createProposal(
vm,
payloads,
GovernanceV3Ethereum.VOTING_PORTAL_ETH_POL,
GovV3Helpers.ipfsHashFile(vm, 'src/20241209_Multi_GHOCCIP151Upgrade/GHOCCIP151Upgrade.md')
);
}
}
17 changes: 17 additions & 0 deletions src/20241209_Multi_GHOCCIP151Upgrade/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {ConfigFile} from '../../generator/types';
export const config: ConfigFile = {
rootOptions: {
pools: ['AaveV3Ethereum', 'AaveV3Arbitrum'],
title: 'GHO CCIP 1.5.1 Upgrade',
shortName: 'GHOCCIP151Upgrade',
date: '20241209',
author: 'Aave Labs',
discussion: '',
snapshot: '',
votingNetwork: 'POLYGON',
},
poolOptions: {
AaveV3Ethereum: {configs: {OTHERS: {}}, cache: {blockNumber: 21366260}},
AaveV3Arbitrum: {configs: {OTHERS: {}}, cache: {blockNumber: 283036001}},
},
};
157 changes: 157 additions & 0 deletions src/20241209_Multi_GHOCCIP151Upgrade/utils/CCIPUtils.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IClient} from 'src/interfaces/ccip/IClient.sol';
import {IRouter} from 'src/interfaces/ccip/IRouter.sol';
import {IInternal} from 'src/interfaces/ccip/IInternal.sol';
import {IEVM2EVMOnRamp} from 'src/interfaces/ccip/IEVM2EVMOnRamp.sol';

library CCIPUtils {
uint64 internal constant ETH_CHAIN_SELECTOR = 5009297550715157269;
uint64 internal constant ARB_CHAIN_SELECTOR = 4949039107694359620;

bytes32 internal constant LEAF_DOMAIN_SEPARATOR =
0x0000000000000000000000000000000000000000000000000000000000000000;
bytes32 internal constant INTERNAL_DOMAIN_SEPARATOR =
0x0000000000000000000000000000000000000000000000000000000000000001;
bytes32 internal constant EVM_2_EVM_MESSAGE_HASH = keccak256('EVM2EVMMessageHashV2');
bytes4 public constant EVM_EXTRA_ARGS_V1_TAG = 0x97a657c9;

struct SourceTokenData {
bytes sourcePoolAddress;
bytes destTokenAddress;
bytes extraData;
uint32 destGasAmount;
}

struct MessageToEventParams {
IClient.EVM2AnyMessage message;
IRouter router;
uint64 sourceChainSelector;
uint256 feeTokenAmount;
address originalSender;
address destinationToken;
}

function generateMessage(
address receiver,
uint256 tokenAmountsLength
) internal pure returns (IClient.EVM2AnyMessage memory) {
return
IClient.EVM2AnyMessage({
receiver: abi.encode(receiver),
data: '',
tokenAmounts: new IClient.EVMTokenAmount[](tokenAmountsLength),
feeToken: address(0),
extraArgs: argsToBytes(IClient.EVMExtraArgsV1({gasLimit: 0}))
});
}

function messageToEvent(
MessageToEventParams memory params
) public view returns (IInternal.EVM2EVMMessage memory) {
uint64 destChainSelector = params.sourceChainSelector == ETH_CHAIN_SELECTOR
? ARB_CHAIN_SELECTOR
: ETH_CHAIN_SELECTOR;
IEVM2EVMOnRamp onRamp = IEVM2EVMOnRamp(params.router.getOnRamp(destChainSelector));

bytes memory args = new bytes(params.message.extraArgs.length - 4);
for (uint256 i = 4; i < params.message.extraArgs.length; ++i) {
args[i - 4] = params.message.extraArgs[i];
}

IInternal.EVM2EVMMessage memory messageEvent = IInternal.EVM2EVMMessage({
sequenceNumber: onRamp.getExpectedNextSequenceNumber(),
feeTokenAmount: params.feeTokenAmount,
sender: params.originalSender,
nonce: onRamp.getSenderNonce(params.originalSender) + 1,
gasLimit: abi.decode(args, (IClient.EVMExtraArgsV1)).gasLimit,
strict: false,
sourceChainSelector: params.sourceChainSelector,
receiver: abi.decode(params.message.receiver, (address)),
data: params.message.data,
tokenAmounts: params.message.tokenAmounts,
sourceTokenData: new bytes[](params.message.tokenAmounts.length),
feeToken: params.router.getWrappedNative(),
messageId: ''
});

for (uint256 i; i < params.message.tokenAmounts.length; ++i) {
messageEvent.sourceTokenData[i] = abi.encode(
SourceTokenData({
sourcePoolAddress: abi.encode(
onRamp.getPoolBySourceToken(destChainSelector, params.message.tokenAmounts[i].token)
),
destTokenAddress: abi.encode(params.destinationToken),
extraData: '',
destGasAmount: getDestGasAmount(onRamp, params.message.tokenAmounts[i].token)
})
);
}

messageEvent.messageId = hash(
messageEvent,
generateMetadataHash(params.sourceChainSelector, destChainSelector, address(onRamp))
);
return messageEvent;
}

function generateMetadataHash(
uint64 sourceChainSelector,
uint64 destChainSelector,
address onRamp
) internal pure returns (bytes32) {
return
keccak256(abi.encode(EVM_2_EVM_MESSAGE_HASH, sourceChainSelector, destChainSelector, onRamp));
}

function argsToBytes(
IClient.EVMExtraArgsV1 memory extraArgs
) internal pure returns (bytes memory bts) {
return abi.encodeWithSelector(EVM_EXTRA_ARGS_V1_TAG, extraArgs);
}

/// @dev Used to hash messages for single-lane ramps.
/// OnRamp hash(EVM2EVMMessage) = OffRamp hash(EVM2EVMMessage)
/// The EVM2EVMMessage's messageId is expected to be the output of this hash function
/// @param original Message to hash
/// @param metadataHash Immutable metadata hash representing a lane with a fixed OnRamp
/// @return hashedMessage hashed message as a keccak256
function hash(
IInternal.EVM2EVMMessage memory original,
bytes32 metadataHash
) internal pure returns (bytes32) {
// Fixed-size message fields are included in nested hash to reduce stack pressure.
// This hashing scheme is also used by RMN. If changing it, please notify the RMN maintainers.
return
keccak256(
abi.encode(
LEAF_DOMAIN_SEPARATOR,
metadataHash,
keccak256(
abi.encode(
original.sender,
original.receiver,
original.sequenceNumber,
original.gasLimit,
original.strict,
original.nonce,
original.feeToken,
original.feeTokenAmount
)
),
keccak256(original.data),
keccak256(abi.encode(original.tokenAmounts)),
keccak256(abi.encode(original.sourceTokenData))
)
);
}

function getDestGasAmount(IEVM2EVMOnRamp onRamp, address token) internal view returns (uint32) {
IEVM2EVMOnRamp.TokenTransferFeeConfig memory config = onRamp.getTokenTransferFeeConfig(token);
return
config.isEnabled
? config.destGasOverhead
: onRamp.getDynamicConfig().defaultTokenDestGasOverhead;
}
}

0 comments on commit c64c0c1

Please sign in to comment.