Skip to content

Commit cfc7eaa

Browse files
committed
Merge branch 'main' into test/phase-one-update
2 parents 6699153 + 9b4a562 commit cfc7eaa

File tree

11 files changed

+261
-16
lines changed

11 files changed

+261
-16
lines changed

.github/workflows/certora-basic.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ concurrency:
77
on:
88
pull_request:
99
branches:
10-
- main
11-
- certora
10+
- "**"
1211
push:
1312
branches:
1413
- main
@@ -18,13 +17,14 @@ on:
1817
jobs:
1918
verify:
2019
runs-on: ubuntu-latest
21-
if:
22-
github.event.pull_request.head.repo.full_name == github.repository || (github.event_name == 'push' &&
23-
github.ref == format('refs/heads/{0}', github.event.repository.default_branch))
20+
# if:
21+
# github.event.pull_request.head.repo.full_name == github.repository || (github.event_name == 'push' &&
22+
# github.ref == format('refs/heads/{0}', github.event.repository.default_branch))
2423
permissions:
2524
contents: read
2625
statuses: write
2726
pull-requests: write
27+
id-token: write
2828
steps:
2929
- uses: actions/checkout@v4
3030
with:
@@ -36,7 +36,7 @@ jobs:
3636
touch applyHarness.patch
3737
make munged
3838
39-
- uses: Certora/certora-run-action@v1
39+
- uses: Certora/certora-run-action@v2
4040
with:
4141
cli-version: 7.29.1
4242
configurations: |-

.github/workflows/certora-stata.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ concurrency:
77
on:
88
pull_request:
99
branches:
10-
- main
11-
- certora
10+
- "**"
1211
push:
1312
branches:
1413
- main
@@ -18,13 +17,14 @@ on:
1817
jobs:
1918
verify:
2019
runs-on: ubuntu-latest
21-
if:
22-
github.event.pull_request.head.repo.full_name == github.repository || (github.event_name == 'push' &&
23-
github.ref == format('refs/heads/{0}', github.event.repository.default_branch))
20+
# if:
21+
# github.event.pull_request.head.repo.full_name == github.repository || (github.event_name == 'push' &&
22+
# github.ref == format('refs/heads/{0}', github.event.repository.default_branch))
2423
permissions:
2524
contents: read
2625
statuses: write
2726
pull-requests: write
27+
id-token: write
2828
steps:
2929
- uses: actions/checkout@v4
3030
with:
@@ -36,7 +36,7 @@ jobs:
3636
touch applyHarness.patch
3737
make munged
3838
39-
- uses: Certora/certora-run-action@v1
39+
- uses: Certora/certora-run-action@v2
4040
with:
4141
cli-version: 7.29.1
4242
configurations: |-
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: "Dependency Review"
2+
on: [pull_request]
3+
4+
permissions:
5+
contents: read
6+
pull-requests: write
7+
8+
jobs:
9+
dependency-review:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: "Checkout Repository"
13+
uses: actions/checkout@v5
14+
- name: "Dependency Review"
15+
uses: actions/dependency-review-action@v4
16+
with:
17+
comment-summary-in-pr: on-failure
18+
fail-on-severity: moderate
19+
license-check: false

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ deploy-phase-one-update-payload :;
8484
--sig "run()" \
8585
--verify --broadcast
8686

87+
# Deploy liquidation data provider. `make deploy-liquidation-data-provider CHAIN=mainnet ACCOUNT=<account>`
88+
deploy-liquidation-data-provider :;
89+
FOUNDRY_PROFILE=${CHAIN} forge script scripts/misc/DeployLiquidationDataProvider.sol:DeployLiquidationDataProvider \
90+
--rpc-url ${CHAIN} --account ${ACCOUNT} --slow --gas-estimate-multiplier 150 \
91+
--chain ${CHAIN} --verifier-url ${VERIFIER_URL} \
92+
--sig "run(address,address)" ${pool} ${addressesProvider} \
93+
--verify --broadcast
94+
8795
# Invariants
8896
echidna:
8997
echidna tests/invariants/Tester.t.sol --contract Tester --config ./tests/invariants/_config/echidna_config.yaml --corpus-dir ./tests/invariants/_corpus/echidna/default/_data/corpus
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.0;
3+
4+
import {LiquidationDataProvider} from '../../src/contracts/helpers/LiquidationDataProvider.sol';
5+
import {Script} from 'forge-std/Script.sol';
6+
7+
contract DeployLiquidationDataProvider is Script {
8+
function run(address pool, address addressesProvider) public returns (address) {
9+
vm.startBroadcast();
10+
LiquidationDataProvider liquidationDataProvider = new LiquidationDataProvider(
11+
pool,
12+
addressesProvider
13+
);
14+
vm.stopBroadcast();
15+
return address(liquidationDataProvider);
16+
}
17+
}

src/contracts/instances/ATokenInstance.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pragma solidity ^0.8.0;
44
import {AToken, IPool, IAaveIncentivesController, IInitializableAToken, Errors, VersionedInitializable} from '../protocol/tokenization/AToken.sol';
55

66
contract ATokenInstance is AToken {
7-
uint256 public constant ATOKEN_REVISION = 1;
7+
uint256 public constant ATOKEN_REVISION = 2;
88

99
constructor(IPool pool) AToken(pool) {}
1010

src/contracts/instances/RwaATokenInstance.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {RwaAToken} from '../protocol/tokenization/RwaAToken.sol';
55
import {IPool, IAaveIncentivesController, IInitializableAToken, Errors, VersionedInitializable} from '../protocol/tokenization/AToken.sol';
66

77
contract RwaATokenInstance is RwaAToken {
8-
uint256 public constant ATOKEN_REVISION = 1;
8+
uint256 public constant ATOKEN_REVISION = 2;
99

1010
constructor(IPool pool) RwaAToken(pool) {}
1111

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.0;
3+
4+
import {Test} from 'forge-std/Test.sol';
5+
import {ATokenInstance, IPool} from 'src/contracts/instances/ATokenInstance.sol';
6+
import {DataTypes} from 'src/contracts/protocol/libraries/types/DataTypes.sol';
7+
8+
contract ATokenRevision_Base is Test {
9+
uint256 internal _preExecSnapshot;
10+
uint256 internal _postExecSnapshot;
11+
12+
IPool internal constant POOL = IPool(0xAe05Cd22df81871bc7cC2a04BeCfb516bFe332C8);
13+
address internal constant NEW_A_TOKEN_INSTANCE = 0xB2668573828029917ffbD1e76270373511818498;
14+
address internal constant NEW_RWA_A_TOKEN_INSTANCE = 0x8CA2a49c7Df42E67F9A532F0d383D648fB7Fe4C9;
15+
address internal constant NEW_REVENUE_SPLITTER = 0x70CC725B8f05e0f230B05C4e91ABc651E121354f;
16+
17+
function setUp() public {
18+
vm.createSelectFork('mainnet', 23320695);
19+
_preExecSnapshot = vm.snapshotState();
20+
_execPayload();
21+
_postExecSnapshot = vm.snapshotState();
22+
}
23+
24+
function test_exec() public view {
25+
address[2] memory aTokenInstances = [NEW_A_TOKEN_INSTANCE, NEW_RWA_A_TOKEN_INSTANCE];
26+
27+
for (uint16 i = 0; i < POOL.getReservesCount(); ++i) {
28+
ATokenInstance aToken = ATokenInstance(
29+
POOL.getReserveData(POOL.getReserveAddressById(i)).aTokenAddress
30+
);
31+
assertEq(aToken.RESERVE_TREASURY_ADDRESS(), NEW_REVENUE_SPLITTER);
32+
assertEq(aToken.ATOKEN_REVISION(), 2);
33+
34+
address aTokenImplementation = _getImplementation(address(aToken));
35+
assertTrue(
36+
aTokenImplementation == aTokenInstances[0] || aTokenImplementation == aTokenInstances[1]
37+
);
38+
}
39+
}
40+
41+
struct ATokenData {
42+
string name;
43+
string symbol;
44+
uint8 decimals;
45+
uint256 totalSupply;
46+
address incentivesController;
47+
uint256 scaledTotalSupply;
48+
bytes32 domainSeparator;
49+
address underlyingAssetAddress;
50+
address pool;
51+
}
52+
53+
function test_aTokenData() public {
54+
uint256 poolReservesCount = POOL.getReservesCount();
55+
56+
ATokenData[] memory aTokenDataPrev = new ATokenData[](poolReservesCount);
57+
ATokenData[] memory aTokenDataNew = new ATokenData[](poolReservesCount);
58+
59+
vm.revertToState(_postExecSnapshot);
60+
for (uint16 i = 0; i < poolReservesCount; ++i) {
61+
address reserve = POOL.getReserveAddressById(i);
62+
ATokenInstance aTokenInstanceNew = ATokenInstance(POOL.getReserveAToken(reserve));
63+
aTokenDataNew[i] = _loadATokenData(aTokenInstanceNew);
64+
assertEq(aTokenInstanceNew.RESERVE_TREASURY_ADDRESS(), NEW_REVENUE_SPLITTER, 'treasury addr');
65+
assertEq(aTokenInstanceNew.ATOKEN_REVISION(), 2, 'revision');
66+
}
67+
68+
vm.revertToState(_preExecSnapshot);
69+
for (uint16 i = 0; i < poolReservesCount; ++i) {
70+
address reserve = POOL.getReserveAddressById(i);
71+
ATokenInstance aTokenInstancePrev = ATokenInstance(POOL.getReserveAToken(reserve));
72+
aTokenDataPrev[i] = _loadATokenData(aTokenInstancePrev);
73+
assertEq(aTokenInstancePrev.ATOKEN_REVISION(), 1);
74+
}
75+
76+
assertEq(abi.encode(aTokenDataPrev), abi.encode(aTokenDataNew), 'aTokenData');
77+
}
78+
79+
function test_reserveData() public {
80+
uint256 poolReservesCount = POOL.getReservesCount();
81+
DataTypes.ReserveDataLegacy[] memory rDataNew = new DataTypes.ReserveDataLegacy[](
82+
poolReservesCount
83+
);
84+
DataTypes.ReserveDataLegacy[] memory rData = new DataTypes.ReserveDataLegacy[](
85+
poolReservesCount
86+
);
87+
88+
vm.revertToState(_postExecSnapshot);
89+
for (uint16 i = 0; i < poolReservesCount; ++i) {
90+
address reserve = POOL.getReserveAddressById(i);
91+
rDataNew[i] = POOL.getReserveData(reserve);
92+
}
93+
94+
vm.revertToState(_preExecSnapshot);
95+
for (uint16 i = 0; i < poolReservesCount; ++i) {
96+
address reserve = POOL.getReserveAddressById(i);
97+
rData[i] = POOL.getReserveData(reserve);
98+
}
99+
100+
assertEq(abi.encode(rData), abi.encode(rDataNew), 'reserveData');
101+
}
102+
function _getImplementation(address proxy) internal view virtual returns (address) {
103+
bytes32 slot = bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1);
104+
return address(uint160(uint256(vm.load(proxy, slot))));
105+
}
106+
107+
function _execPayload() internal {
108+
address EMERGENCY_MULTISIG = 0x13B57382c36BAB566E75C72303622AF29E27e1d3;
109+
address TARGET = 0x9641d764fc13c8B624c04430C7356C1C7C8102e2; // safe transaction batcher
110+
bytes
111+
memory TARGET_CALLDATA = hex'8d80ff0a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000fc80083cb1b4af26eef6463ac20afbac9c0e2e017202f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a4bb01c37c000000000000000000000000000000000000000000000000000000000000002000000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f00000000000000000000000070cc725b8f05e0f230b05c4e91abc651e121354f0000000000000000000000001d5d386a90cea8acea9fa75389e97cf5f1ae21d300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000b2668573828029917ffbd1e76270373511818498000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000144161766520486f72697a6f6e205257412047484f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a61486f7252776147484f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083cb1b4af26eef6463ac20afbac9c0e2e017202f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a4bb01c37c0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000070cc725b8f05e0f230b05c4e91abc651e121354f0000000000000000000000001d5d386a90cea8acea9fa75389e97cf5f1ae21d300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000b2668573828029917ffbd1e76270373511818498000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000154161766520486f72697a6f6e2052574120555344430000000000000000000000000000000000000000000000000000000000000000000000000000000000000b61486f725277615553444300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083cb1b4af26eef6463ac20afbac9c0e2e017202f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a4bb01c37c00000000000000000000000000000000000000000000000000000000000000200000000000000000000000008292bb45bf1ee4d140127049757c2e0ff06317ed00000000000000000000000070cc725b8f05e0f230b05c4e91abc651e121354f0000000000000000000000001d5d386a90cea8acea9fa75389e97cf5f1ae21d300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000b2668573828029917ffbd1e76270373511818498000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000164161766520486f72697a6f6e2052574120524c55534400000000000000000000000000000000000000000000000000000000000000000000000000000000000c61486f72527761524c555344000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083cb1b4af26eef6463ac20afbac9c0e2e017202f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a4bb01c37c000000000000000000000000000000000000000000000000000000000000002000000000000000000000000043415eb6ff9db7e26a15b704e7a3edce97d31c4e00000000000000000000000070cc725b8f05e0f230b05c4e91abc651e121354f0000000000000000000000001d5d386a90cea8acea9fa75389e97cf5f1ae21d300000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000008ca2a49c7df42e67f9a532f0d383d648fb7fe4c9000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000154161766520486f72697a6f6e2052574120555354420000000000000000000000000000000000000000000000000000000000000000000000000000000000000b61486f725277615553544200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083cb1b4af26eef6463ac20afbac9c0e2e017202f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a4bb01c37c000000000000000000000000000000000000000000000000000000000000002000000000000000000000000014d60e7fdc0d71d8611742720e4c50e7a974020c00000000000000000000000070cc725b8f05e0f230b05c4e91abc651e121354f0000000000000000000000001d5d386a90cea8acea9fa75389e97cf5f1ae21d300000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000008ca2a49c7df42e67f9a532f0d383d648fb7fe4c9000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000154161766520486f72697a6f6e2052574120555343430000000000000000000000000000000000000000000000000000000000000000000000000000000000000b61486f725277615553434300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083cb1b4af26eef6463ac20afbac9c0e2e017202f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a4bb01c37c0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000136471a34f6ef19fe571effc1ca711fdb8e49f2b00000000000000000000000070cc725b8f05e0f230b05c4e91abc651e121354f0000000000000000000000001d5d386a90cea8acea9fa75389e97cf5f1ae21d300000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000008ca2a49c7df42e67f9a532f0d383d648fb7fe4c9000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000154161766520486f72697a6f6e2052574120555359430000000000000000000000000000000000000000000000000000000000000000000000000000000000000b61486f725277615553594300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083cb1b4af26eef6463ac20afbac9c0e2e017202f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a4bb01c37c00000000000000000000000000000000000000000000000000000000000000200000000000000000000000008c213ee79581ff4984583c6a801e5263418c4b8600000000000000000000000070cc725b8f05e0f230b05c4e91abc651e121354f0000000000000000000000001d5d386a90cea8acea9fa75389e97cf5f1ae21d300000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000008ca2a49c7df42e67f9a532f0d383d648fb7fe4c9000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000164161766520486f72697a6f6e20525741204a5452535900000000000000000000000000000000000000000000000000000000000000000000000000000000000c61486f725277614a54525359000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083cb1b4af26eef6463ac20afbac9c0e2e017202f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a4bb01c37c00000000000000000000000000000000000000000000000000000000000000200000000000000000000000005a0f93d040de44e78f251b03c43be9cf317dcf6400000000000000000000000070cc725b8f05e0f230b05c4e91abc651e121354f0000000000000000000000001d5d386a90cea8acea9fa75389e97cf5f1ae21d300000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000008ca2a49c7df42e67f9a532f0d383d648fb7fe4c9000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000154161766520486f72697a6f6e20525741204a4141410000000000000000000000000000000000000000000000000000000000000000000000000000000000000b61486f725277614a4141410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
112+
vm.store(EMERGENCY_MULTISIG, bytes32(uint256(4)), bytes32(uint256(1))); // reset signer threshold to one
113+
address SIGNER = 0xCe5004e7202b5194c53C0Eed784cEf2B96461e0b;
114+
vm.prank(SIGNER);
115+
ISafeAccount(EMERGENCY_MULTISIG).execTransaction({
116+
to: TARGET,
117+
value: 0,
118+
data: TARGET_CALLDATA,
119+
operation: 1, // 1 => delegatecall
120+
safeTxGas: 0,
121+
baseGas: 0,
122+
gasPrice: 0,
123+
gasToken: 0x0000000000000000000000000000000000000000,
124+
refundReceiver: payable(0x0000000000000000000000000000000000000000),
125+
signatures: abi.encodePacked(uint256(uint160(SIGNER)), uint256(0), uint8(1)) // r, s, v
126+
});
127+
}
128+
129+
function _loadATokenData(ATokenInstance aToken) internal view returns (ATokenData memory) {
130+
return
131+
ATokenData({
132+
name: aToken.name(),
133+
symbol: aToken.symbol(),
134+
decimals: aToken.decimals(),
135+
totalSupply: aToken.totalSupply(),
136+
incentivesController: address(aToken.getIncentivesController()),
137+
scaledTotalSupply: aToken.scaledTotalSupply(),
138+
domainSeparator: aToken.DOMAIN_SEPARATOR(),
139+
underlyingAssetAddress: aToken.UNDERLYING_ASSET_ADDRESS(),
140+
pool: address(aToken.POOL())
141+
});
142+
}
143+
}
144+
145+
interface ISafeAccount {
146+
function execTransaction(
147+
address to,
148+
uint256 value,
149+
bytes calldata data,
150+
uint8 operation,
151+
uint256 safeTxGas,
152+
uint256 baseGas,
153+
uint256 gasPrice,
154+
address gasToken,
155+
address payable refundReceiver,
156+
bytes memory signatures
157+
) external payable returns (bool success);
158+
}

0 commit comments

Comments
 (0)