Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
2 changes: 1 addition & 1 deletion src/contracts/instances/ATokenInstance.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity ^0.8.0;
import {AToken, IPool, IAaveIncentivesController, IInitializableAToken, Errors, VersionedInitializable} from '../protocol/tokenization/AToken.sol';

contract ATokenInstance is AToken {
uint256 public constant ATOKEN_REVISION = 1;
uint256 public constant ATOKEN_REVISION = 2;

constructor(IPool pool) AToken(pool) {}

Expand Down
2 changes: 1 addition & 1 deletion src/contracts/instances/RwaATokenInstance.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {RwaAToken} from '../protocol/tokenization/RwaAToken.sol';
import {IPool, IAaveIncentivesController, IInitializableAToken, Errors, VersionedInitializable} from '../protocol/tokenization/AToken.sol';

contract RwaATokenInstance is RwaAToken {
uint256 public constant ATOKEN_REVISION = 1;
uint256 public constant ATOKEN_REVISION = 2;

constructor(IPool pool) RwaAToken(pool) {}

Expand Down
158 changes: 158 additions & 0 deletions tests/deployments/ATokenRevision.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import {Test} from 'forge-std/Test.sol';
import {ATokenInstance, IPool} from 'src/contracts/instances/ATokenInstance.sol';
import {DataTypes} from 'src/contracts/protocol/libraries/types/DataTypes.sol';

contract ATokenRevision_Base is Test {
uint256 internal _preExecSnapshot;
uint256 internal _postExecSnapshot;

IPool internal constant POOL = IPool(0xAe05Cd22df81871bc7cC2a04BeCfb516bFe332C8);
address internal constant NEW_A_TOKEN_INSTANCE = 0xB2668573828029917ffbD1e76270373511818498;
address internal constant NEW_RWA_A_TOKEN_INSTANCE = 0x8CA2a49c7Df42E67F9A532F0d383D648fB7Fe4C9;
address internal constant NEW_REVENUE_SPLITTER = 0x70CC725B8f05e0f230B05C4e91ABc651E121354f;

function setUp() public {
vm.createSelectFork('mainnet', 23320695);
_preExecSnapshot = vm.snapshotState();
_execPayload();
_postExecSnapshot = vm.snapshotState();
}

function test_exec() public view {
address[2] memory aTokenInstances = [NEW_A_TOKEN_INSTANCE, NEW_RWA_A_TOKEN_INSTANCE];

for (uint16 i = 0; i < POOL.getReservesCount(); ++i) {
ATokenInstance aToken = ATokenInstance(
POOL.getReserveData(POOL.getReserveAddressById(i)).aTokenAddress
);
assertEq(aToken.RESERVE_TREASURY_ADDRESS(), NEW_REVENUE_SPLITTER);
assertEq(aToken.ATOKEN_REVISION(), 2);

address aTokenImplementation = _getImplementation(address(aToken));
assertTrue(
aTokenImplementation == aTokenInstances[0] || aTokenImplementation == aTokenInstances[1]
);
}
}

struct ATokenData {
string name;
string symbol;
uint8 decimals;
uint256 totalSupply;
address incentivesController;
uint256 scaledTotalSupply;
bytes32 domainSeparator;
address underlyingAssetAddress;
address pool;
}

function test_aTokenData() public {
uint256 poolReservesCount = POOL.getReservesCount();

ATokenData[] memory aTokenDataPrev = new ATokenData[](poolReservesCount);
ATokenData[] memory aTokenDataNew = new ATokenData[](poolReservesCount);

vm.revertToState(_postExecSnapshot);
for (uint16 i = 0; i < poolReservesCount; ++i) {
address reserve = POOL.getReserveAddressById(i);
ATokenInstance aTokenInstanceNew = ATokenInstance(POOL.getReserveAToken(reserve));
aTokenDataNew[i] = _loadATokenData(aTokenInstanceNew);
assertEq(aTokenInstanceNew.RESERVE_TREASURY_ADDRESS(), NEW_REVENUE_SPLITTER, 'treasury addr');
assertEq(aTokenInstanceNew.ATOKEN_REVISION(), 2, 'revision');
}

vm.revertToState(_preExecSnapshot);
for (uint16 i = 0; i < poolReservesCount; ++i) {
address reserve = POOL.getReserveAddressById(i);
ATokenInstance aTokenInstancePrev = ATokenInstance(POOL.getReserveAToken(reserve));
aTokenDataPrev[i] = _loadATokenData(aTokenInstancePrev);
assertEq(aTokenInstancePrev.ATOKEN_REVISION(), 1);
}

assertEq(abi.encode(aTokenDataPrev), abi.encode(aTokenDataNew), 'aTokenData');
}

function test_reserveData() public {
uint256 poolReservesCount = POOL.getReservesCount();
DataTypes.ReserveDataLegacy[] memory rDataNew = new DataTypes.ReserveDataLegacy[](
poolReservesCount
);
DataTypes.ReserveDataLegacy[] memory rData = new DataTypes.ReserveDataLegacy[](
poolReservesCount
);

vm.revertToState(_postExecSnapshot);
for (uint16 i = 0; i < poolReservesCount; ++i) {
address reserve = POOL.getReserveAddressById(i);
rDataNew[i] = POOL.getReserveData(reserve);
}

vm.revertToState(_preExecSnapshot);
for (uint16 i = 0; i < poolReservesCount; ++i) {
address reserve = POOL.getReserveAddressById(i);
rData[i] = POOL.getReserveData(reserve);
}

assertEq(abi.encode(rData), abi.encode(rDataNew), 'reserveData');
}
function _getImplementation(address proxy) internal view virtual returns (address) {
bytes32 slot = bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1);
return address(uint160(uint256(vm.load(proxy, slot))));
}

function _execPayload() internal {
address EMERGENCY_MULTISIG = 0x13B57382c36BAB566E75C72303622AF29E27e1d3;
address TARGET = 0x9641d764fc13c8B624c04430C7356C1C7C8102e2; // safe transaction batcher
bytes
memory TARGET_CALLDATA = hex'8d80ff0a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000fc80083cb1b4af26eef6463ac20afbac9c0e2e017202f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a4bb01c37c000000000000000000000000000000000000000000000000000000000000002000000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f00000000000000000000000070cc725b8f05e0f230b05c4e91abc651e121354f0000000000000000000000001d5d386a90cea8acea9fa75389e97cf5f1ae21d300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000b2668573828029917ffbd1e76270373511818498000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000144161766520486f72697a6f6e205257412047484f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a61486f7252776147484f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083cb1b4af26eef6463ac20afbac9c0e2e017202f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a4bb01c37c0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000070cc725b8f05e0f230b05c4e91abc651e121354f0000000000000000000000001d5d386a90cea8acea9fa75389e97cf5f1ae21d300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000b2668573828029917ffbd1e76270373511818498000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000154161766520486f72697a6f6e2052574120555344430000000000000000000000000000000000000000000000000000000000000000000000000000000000000b61486f725277615553444300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083cb1b4af26eef6463ac20afbac9c0e2e017202f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a4bb01c37c00000000000000000000000000000000000000000000000000000000000000200000000000000000000000008292bb45bf1ee4d140127049757c2e0ff06317ed00000000000000000000000070cc725b8f05e0f230b05c4e91abc651e121354f0000000000000000000000001d5d386a90cea8acea9fa75389e97cf5f1ae21d300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000b2668573828029917ffbd1e76270373511818498000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000164161766520486f72697a6f6e2052574120524c55534400000000000000000000000000000000000000000000000000000000000000000000000000000000000c61486f72527761524c555344000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083cb1b4af26eef6463ac20afbac9c0e2e017202f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a4bb01c37c000000000000000000000000000000000000000000000000000000000000002000000000000000000000000043415eb6ff9db7e26a15b704e7a3edce97d31c4e00000000000000000000000070cc725b8f05e0f230b05c4e91abc651e121354f0000000000000000000000001d5d386a90cea8acea9fa75389e97cf5f1ae21d300000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000008ca2a49c7df42e67f9a532f0d383d648fb7fe4c9000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000154161766520486f72697a6f6e2052574120555354420000000000000000000000000000000000000000000000000000000000000000000000000000000000000b61486f725277615553544200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083cb1b4af26eef6463ac20afbac9c0e2e017202f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a4bb01c37c000000000000000000000000000000000000000000000000000000000000002000000000000000000000000014d60e7fdc0d71d8611742720e4c50e7a974020c00000000000000000000000070cc725b8f05e0f230b05c4e91abc651e121354f0000000000000000000000001d5d386a90cea8acea9fa75389e97cf5f1ae21d300000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000008ca2a49c7df42e67f9a532f0d383d648fb7fe4c9000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000154161766520486f72697a6f6e2052574120555343430000000000000000000000000000000000000000000000000000000000000000000000000000000000000b61486f725277615553434300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083cb1b4af26eef6463ac20afbac9c0e2e017202f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a4bb01c37c0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000136471a34f6ef19fe571effc1ca711fdb8e49f2b00000000000000000000000070cc725b8f05e0f230b05c4e91abc651e121354f0000000000000000000000001d5d386a90cea8acea9fa75389e97cf5f1ae21d300000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000008ca2a49c7df42e67f9a532f0d383d648fb7fe4c9000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000154161766520486f72697a6f6e2052574120555359430000000000000000000000000000000000000000000000000000000000000000000000000000000000000b61486f725277615553594300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083cb1b4af26eef6463ac20afbac9c0e2e017202f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a4bb01c37c00000000000000000000000000000000000000000000000000000000000000200000000000000000000000008c213ee79581ff4984583c6a801e5263418c4b8600000000000000000000000070cc725b8f05e0f230b05c4e91abc651e121354f0000000000000000000000001d5d386a90cea8acea9fa75389e97cf5f1ae21d300000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000008ca2a49c7df42e67f9a532f0d383d648fb7fe4c9000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000164161766520486f72697a6f6e20525741204a5452535900000000000000000000000000000000000000000000000000000000000000000000000000000000000c61486f725277614a54525359000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083cb1b4af26eef6463ac20afbac9c0e2e017202f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a4bb01c37c00000000000000000000000000000000000000000000000000000000000000200000000000000000000000005a0f93d040de44e78f251b03c43be9cf317dcf6400000000000000000000000070cc725b8f05e0f230b05c4e91abc651e121354f0000000000000000000000001d5d386a90cea8acea9fa75389e97cf5f1ae21d300000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000008ca2a49c7df42e67f9a532f0d383d648fb7fe4c9000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000154161766520486f72697a6f6e20525741204a4141410000000000000000000000000000000000000000000000000000000000000000000000000000000000000b61486f725277614a4141410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
vm.store(EMERGENCY_MULTISIG, bytes32(uint256(4)), bytes32(uint256(1))); // reset signer threshold to one
address SIGNER = 0xCe5004e7202b5194c53C0Eed784cEf2B96461e0b;
vm.prank(SIGNER);
ISafeAccount(EMERGENCY_MULTISIG).execTransaction({
to: TARGET,
value: 0,
data: TARGET_CALLDATA,
operation: 1, // 1 => delegatecall
safeTxGas: 0,
baseGas: 0,
gasPrice: 0,
gasToken: 0x0000000000000000000000000000000000000000,
refundReceiver: payable(0x0000000000000000000000000000000000000000),
signatures: abi.encodePacked(uint256(uint160(SIGNER)), uint256(0), uint8(1)) // r, s, v
});
}

function _loadATokenData(ATokenInstance aToken) internal view returns (ATokenData memory) {
return
ATokenData({
name: aToken.name(),
symbol: aToken.symbol(),
decimals: aToken.decimals(),
totalSupply: aToken.totalSupply(),
incentivesController: address(aToken.getIncentivesController()),
scaledTotalSupply: aToken.scaledTotalSupply(),
domainSeparator: aToken.DOMAIN_SEPARATOR(),
underlyingAssetAddress: aToken.UNDERLYING_ASSET_ADDRESS(),
pool: address(aToken.POOL())
});
}
}

interface ISafeAccount {
function execTransaction(
address to,
uint256 value,
bytes calldata data,
uint8 operation,
uint256 safeTxGas,
uint256 baseGas,
uint256 gasPrice,
address gasToken,
address payable refundReceiver,
bytes memory signatures
) external payable returns (bool success);
}
Loading