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

feat: stata token v2 (#52) #53

Merged
merged 3 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
78 changes: 78 additions & 0 deletions .github/workflows/certora-stata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: certora-stata

on:
push:
branches:
- main
pull_request:
branches:
- main

workflow_dispatch:

jobs:
verify:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
with:
submodules: recursive

- name: Install python
uses: actions/setup-python@v2
with: { python-version: 3.9 }

- name: Install java
uses: actions/setup-java@v1
with: { java-version: "11", java-package: jre }

- name: Install certora cli
run: pip install certora-cli==7.14.2
- name: Install solc
run: |
wget https://github.com/ethereum/solidity/releases/download/v0.8.20/solc-static-linux
chmod +x solc-static-linux
sudo mv solc-static-linux /usr/local/bin/solc8.20

- name: Verify rule ${{ matrix.rule }}
run: |
cd certora/stata
touch applyHarness.patch
make munged
cd ../..
certoraRun certora/stata/conf/${{ matrix.rule }}
env:
CERTORAKEY: ${{ secrets.CERTORAKEY }}

strategy:
fail-fast: false
max-parallel: 16
matrix:
rule:
- verifyERC4626.conf --rule previewRedeemIndependentOfBalance previewMintAmountCheck previewDepositIndependentOfAllowanceApprove previewWithdrawAmountCheck previewWithdrawIndependentOfBalance2 previewWithdrawIndependentOfBalance1 previewRedeemIndependentOfMaxRedeem1 previewRedeemAmountCheck previewRedeemIndependentOfMaxRedeem2 amountConversionRoundedDown withdrawCheck redeemCheck redeemATokensCheck convertToAssetsCheck convertToSharesCheck toAssetsDoesNotRevert sharesConversionRoundedDown toSharesDoesNotRevert previewDepositAmountCheck maxRedeemCompliance maxWithdrawConversionCompliance previewMintIndependentOfAllowance
- verifyERC4626.conf --rule maxMintMustntRevert maxDepositMustntRevert maxRedeemMustntRevert maxWithdrawMustntRevert totalAssetsMustntRevert
# Timeout
# - verifyERC4626.conf --rule previewWithdrawIndependentOfMaxWithdraw
- verifyERC4626MintDepositSummarization.conf --rule depositCheckIndexGRayAssert2 depositATokensCheckIndexGRayAssert2 depositWithPermitCheckIndexGRayAssert2 depositCheckIndexERayAssert2 depositATokensCheckIndexERayAssert2 depositWithPermitCheckIndexERayAssert2 mintCheckIndexGRayUpperBound mintCheckIndexGRayLowerBound mintCheckIndexEqualsRay
- verifyERC4626DepositSummarization.conf --rule depositCheckIndexGRayAssert1 depositATokensCheckIndexGRayAssert1 depositWithPermitCheckIndexGRayAssert1 depositCheckIndexERayAssert1 depositATokensCheckIndexERayAssert1 depositWithPermitCheckIndexERayAssert1
- verifyERC4626Extended.conf --rule previewWithdrawRoundingRange previewRedeemRoundingRange amountConversionPreserved sharesConversionPreserved accountsJoiningSplittingIsLimited convertSumOfAssetsPreserved previewDepositSameAsDeposit previewMintSameAsMint
- verifyERC4626Extended.conf --rule maxDepositConstant
- verifyERC4626Extended.conf --rule redeemSum
- verifyERC4626Extended.conf --rule redeemATokensSum
- verifyAToken.conf --rule aTokenBalanceIsFixed_for_collectAndUpdateRewards aTokenBalanceIsFixed_for_claimRewards aTokenBalanceIsFixed_for_claimRewardsOnBehalf
- verifyAToken.conf --rule aTokenBalanceIsFixed_for_claimSingleRewardOnBehalf aTokenBalanceIsFixed_for_claimRewardsToSelf
- verifyStataToken.conf --rule rewardsConsistencyWhenSufficientRewardsExist
- verifyStataToken.conf --rule rewardsConsistencyWhenInsufficientRewards
- verifyStataToken.conf --rule totalClaimableRewards_stable
- verifyStataToken.conf --rule solvency_positive_total_supply_only_if_positive_asset
- verifyStataToken.conf --rule solvency_total_asset_geq_total_supply
- verifyStataToken.conf --rule singleAssetAccruedRewards
- verifyStataToken.conf --rule totalAssets_stable
- verifyStataToken.conf --rule getClaimableRewards_stable
- verifyStataToken.conf --rule getClaimableRewards_stable_after_deposit
- verifyStataToken.conf --rule getClaimableRewards_stable_after_refreshRewardTokens
- verifyStataToken.conf --rule getClaimableRewardsBefore_leq_claimed_claimRewardsOnBehalf
- verifyStataToken.conf --rule rewardsTotalDeclinesOnlyByClaim
- verifyDoubleClaim.conf --rule prevent_duplicate_reward_claiming_single_reward_sufficient
- verifyDoubleClaim.conf --rule prevent_duplicate_reward_claiming_single_reward_insufficient
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ coverage :; forge coverage --report lcov && \
download :; cast etherscan-source --chain ${chain} -d src/etherscan/${chain}_${address} ${address}
git-diff :
@mkdir -p diffs
@npx prettier ${before} ${after} --write
@printf '%s\n%s\n%s\n' "\`\`\`diff" "$$(git diff --no-index --diff-algorithm=patience --ignore-space-at-eol ${before} ${after})" "\`\`\`" > diffs/${out}.md
Binary file added audits/11-09-2024_Certora_StataTokenV2.pdf
Binary file not shown.
Binary file modified bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions certora/conf/AToken.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
"process": "emv",
"solc": "solc8.19",
"verify": "ATokenHarness:certora/specs/AToken.spec",
// "build_cache": true,
"msg": "aToken spec"
}
1 change: 1 addition & 0 deletions certora/conf/NEW-pool-no-summarizations.conf
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"depositUpdatesUserATokenSuperBalance",
"depositCannotChangeOthersATokenSuperBalance"
],
// "build_cache": true,
"parametric_contracts": ["PoolHarness"],
"msg": "pool-no-summarizations::partial rules",
}
1 change: 1 addition & 0 deletions certora/conf/NEW-pool-simple-properties.conf
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"cannotBorrowOnReserveDisabledForBorrowing",
"cannotBorrowOnFrozenReserve"
],
// "build_cache": true,
"parametric_contracts": ["PoolHarness"],
"msg": "pool-simple-properties::ALL",
}
1 change: 1 addition & 0 deletions certora/conf/ReserveConfiguration.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
],
"rule_sanity": "basic", // from time to time, use "advanced" instead of "basic"
"solc": "solc8.19",
// "build_cache": true,
"verify": "ReserveConfigurationHarness:certora/specs/ReserveConfiguration.spec"
}
1 change: 1 addition & 0 deletions certora/conf/StableDebtToken.conf
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@
"optimistic_loop": true,
"process": "emv",
"solc": "solc8.19",
// "build_cache": true,
"verify": "StableDebtTokenHarness:certora/specs/StableDebtToken.spec"
}
1 change: 1 addition & 0 deletions certora/conf/UserConfiguration.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
"-useBitVectorTheory"
],
"solc": "solc8.19",
// "build_cache": true,
"verify": "UserConfigurationHarness:certora/specs/UserConfiguration.spec"
}
1 change: 1 addition & 0 deletions certora/conf/VariableDebtToken.conf
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
"optimistic_loop": true,
"process": "emv",
"solc": "solc8.19",
// "build_cache": true,
"verify": "VariableDebtTokenHarness:certora/specs/VariableDebtToken.spec"
}
2 changes: 1 addition & 1 deletion certora/scripts/run-all.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
CMN=""
#CMN="--compilation_steps_only"



Expand Down
12 changes: 6 additions & 6 deletions certora/specs/NEW-pool-base.spec
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,19 @@ methods {
function _.transfer(address, uint256) external => DISPATCHER(true);
function _.transferFrom(address, address, uint256) external => DISPATCHER(true);
function _.approve(address, uint256) external => DISPATCHER(true);
function _.mint(address, uint256) external => DISPATCHER(true);
function _.burn(uint256) external => DISPATCHER(true);
//function _.mint(address, uint256) external => DISPATCHER(true);
//function _.burn(uint256) external => DISPATCHER(true);
function _.balanceOf(address) external => DISPATCHER(true);

function _.totalSupply() external => DISPATCHER(true);

// ATOKEN
function _.mint(address user, uint256 amount, uint256 index) external => DISPATCHER(true);
function _.burn(address user, address receiverOfUnderlying, uint256 amount, uint256 index) external => DISPATCHER(true);
//function _.mint(address user, uint256 amount, uint256 index) external => DISPATCHER(true);
//function _.burn(address user, address receiverOfUnderlying, uint256 amount, uint256 index) external => DISPATCHER(true);
function _.mintToTreasury(uint256 amount, uint256 index) external => DISPATCHER(true);
function _.transferOnLiquidation(address from, address to, uint256 value) external => DISPATCHER(true);
function _.transferUnderlyingTo(address user, uint256 amount) external => DISPATCHER(true);
function _.handleRepayment(address user, uint256 amount) external => DISPATCHER(true);
// function _.handleRepayment(address user, uint256 amount) external => DISPATCHER(true);
function _.permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external => DISPATCHER(true);
function _.ATokenBalanceOf(address user) external => DISPATCHER(true);

Expand All @@ -62,7 +62,7 @@ methods {
function _.getReserveNormalizedIncome(address asset) external => DISPATCHER(true);
function _.getReserveNormalizedVariableDebt(address asset) external => DISPATCHER(true);
function _.getACLManager() external => DISPATCHER(true);
function _.isBridge(address) external => DISPATCHER(true);
//function _.isBridge(address) external => DISPATCHER(true);

// StableDebt
function _.mint(address user, address onBehalfOf, uint256 amount, uint256 rate) external => DISPATCHER(true);
Expand Down
2 changes: 1 addition & 1 deletion certora/specs/NEW-pool-no-summarizations.spec
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ methods {
function _.symbol() external => DISPATCHER(true);
function _.isFlashBorrower(address a) external => DISPATCHER(true);

function _.executeOperation(address[] a, uint256[]b, uint256[]c, address d, bytes e) external => DISPATCHER(true);
// function _.executeOperation(address[] a, uint256[]b, uint256[]c, address d, bytes e) external => DISPATCHER(true);

function _.getAverageStableRate() external => DISPATCHER(true);
function _.isPoolAdmin(address a) external => DISPATCHER(true);
Expand Down
33 changes: 33 additions & 0 deletions certora/stata/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
default: help

PATCH = applyHarness.patch
CONTRACTS_DIR = ../../src
LIBS_DIR = ../../lib
MUNGED_SRC = munged/src
MUNGED_LIB = munged/lib
MUNGED_DIR = munged

help:
@echo "usage:"
@echo " make clean: remove all generated files (those ignored by git)"
@echo " make $(MUNGED_DIR): create $(MUNGED_DIR) directory by applying the patch file to $(CONTRACTS_DIR)"
@echo " make record: record a new patch file capturing the differences between $(CONTRACTS_DIR) and $(MUNGED_DIR)"

munged: $(wildcard $(CONTRACTS_DIR)/*.sol) $(PATCH)
rm -rf $@
mkdir $@
cp -r ../../lib $@
cp -r ../../src $@
patch -p0 -d $@ < $(PATCH)

record:
mkdir tmp
cp -r ../../lib tmp
cp -r ../../src tmp
diff -ruN tmp $(MUNGED_DIR) | sed 's+tmp/++g' | sed 's+$(MUNGED_DIR)/++g' > $(PATCH)
rm -rf tmp

clean:
git clean -fdX
touch $(PATCH)

48 changes: 48 additions & 0 deletions certora/stata/applyHarness.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
diff -ruN .gitignore .gitignore
--- .gitignore 1970-01-01 02:00:00
+++ .gitignore 2024-09-04 13:59:46
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff -ruN src/core/instances/ATokenInstance.sol src/core/instances/ATokenInstance.sol
--- src/core/instances/ATokenInstance.sol 2024-09-05 19:01:54
+++ src/core/instances/ATokenInstance.sol 2024-09-05 11:33:23
@@ -35,15 +35,15 @@

_domainSeparator = _calculateDomainSeparator();

- emit Initialized(
- underlyingAsset,
- address(POOL),
- treasury,
- address(incentivesController),
- aTokenDecimals,
- aTokenName,
- aTokenSymbol,
- params
- );
+ // emit Initialized(
+ // underlyingAsset,
+ // address(POOL),
+ // treasury,
+ // address(incentivesController),
+ // aTokenDecimals,
+ // aTokenName,
+ // aTokenSymbol,
+ // params
+ // );
}
}
diff -ruN src/periphery/contracts/static-a-token/ERC20AaveLMUpgradeable.sol src/periphery/contracts/static-a-token/ERC20AaveLMUpgradeable.sol
--- src/periphery/contracts/static-a-token/ERC20AaveLMUpgradeable.sol 2024-09-05 19:01:54
+++ src/periphery/contracts/static-a-token/ERC20AaveLMUpgradeable.sol 2024-09-05 13:48:31
@@ -147,7 +147,7 @@
}

///@inheritdoc IERC20AaveLM
- function rewardTokens() external view returns (address[] memory) {
+ function rewardTokens() public view returns (address[] memory) {
ERC20AaveLMStorage storage $ = _getERC20AaveLMStorage();
return $._rewardTokens;
}
40 changes: 40 additions & 0 deletions certora/stata/conf/verifyAToken.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"files": [
"certora/stata/harness/StataTokenV2Harness.sol",
"certora/stata/harness/pool/SymbolicLendingPool.sol",
"certora/stata/harness/rewards/RewardsControllerHarness.sol",
"certora/stata/harness/rewards/TransferStrategyHarness.sol",
"certora/stata/harness/tokens/DummyERC20_aTokenUnderlying.sol",
"certora/stata/harness/tokens/DummyERC20_rewardToken.sol",
"certora/stata/munged/src/core/instances/ATokenInstance.sol",
],
"link": [
"SymbolicLendingPool:aToken=ATokenInstance",
"SymbolicLendingPool:underlyingToken=DummyERC20_aTokenUnderlying",
"TransferStrategyHarness:INCENTIVES_CONTROLLER=RewardsControllerHarness",
"TransferStrategyHarness:REWARD=DummyERC20_rewardToken",
"ATokenInstance:POOL=SymbolicLendingPool",
"ATokenInstance:_incentivesController=RewardsControllerHarness",
"ATokenInstance:_underlyingAsset=DummyERC20_aTokenUnderlying",
"StataTokenV2Harness:INCENTIVES_CONTROLLER=RewardsControllerHarness",
"StataTokenV2Harness:POOL=SymbolicLendingPool",
"StataTokenV2Harness:_reward_A=DummyERC20_rewardToken"
],
"packages": [
"aave-v3-core/=certora/stata/munged/src/core",
"aave-v3-periphery/=certora/stata/munged/src/periphery",
"solidity-utils/=certora/stata/munged/lib/solidity-utils/src",
"forge-std/=certora/stata/munged/lib/forge-std/src",
"openzeppelin-contracts-upgradeable/=certora/stata/munged/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable",
"openzeppelin-contracts/=certora/stata/munged/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts",
"@openzeppelin/contracts/=certora/stata/munged/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts",
],
"loop_iter": "1",
"msg": "aToken properties",
"optimistic_hashing": true,
"optimistic_loop": true,
"solc": "solc8.20",
"smt_timeout": "1400",
"verify": "StataTokenV2Harness:certora/stata/specs/StataToken/aTokenProperties.spec",
"build_cache": true,
}
40 changes: 40 additions & 0 deletions certora/stata/conf/verifyDoubleClaim.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"files": [
"certora/stata/harness/StataTokenV2Harness.sol",
"certora/stata/harness/pool/SymbolicLendingPool.sol",
"certora/stata/harness/rewards/RewardsControllerHarness.sol",
"certora/stata/harness/rewards/TransferStrategyHarness.sol",
"certora/stata/harness/tokens/DummyERC20_aTokenUnderlying.sol",
"certora/stata/harness/tokens/DummyERC20_rewardToken.sol",
"certora/stata/munged/src/core/instances/ATokenInstance.sol",
],
"link": [
"SymbolicLendingPool:aToken=ATokenInstance",
"SymbolicLendingPool:underlyingToken=DummyERC20_aTokenUnderlying",
"TransferStrategyHarness:INCENTIVES_CONTROLLER=RewardsControllerHarness",
"TransferStrategyHarness:REWARD=DummyERC20_rewardToken",
"ATokenInstance:POOL=SymbolicLendingPool",
"ATokenInstance:_incentivesController=RewardsControllerHarness",
"ATokenInstance:_underlyingAsset=DummyERC20_aTokenUnderlying",
"StataTokenV2Harness:INCENTIVES_CONTROLLER=RewardsControllerHarness",
"StataTokenV2Harness:POOL=SymbolicLendingPool",
"StataTokenV2Harness:_reward_A=DummyERC20_rewardToken"
],
"packages": [
"aave-v3-core/=certora/stata/munged/src/core",
"aave-v3-periphery/=certora/stata/munged/src/periphery",
"solidity-utils/=certora/stata/munged/lib/solidity-utils/src",
"forge-std/=certora/stata/munged/lib/forge-std/src",
"openzeppelin-contracts-upgradeable/=certora/stata/munged/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable",
"openzeppelin-contracts/=certora/stata/munged/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts",
"@openzeppelin/contracts/=certora/stata/munged/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts",
],
"verify":"StataTokenV2Harness:certora/stata/specs/StataToken/double_claim.spec",
"solc": "solc8.20",
"msg": "Multi rewards - double claim properties",
"optimistic_loop": true,
"smt_timeout": "2000",
"loop_iter": "2",
"optimistic_hashing": true,
"build_cache": true,
}
40 changes: 40 additions & 0 deletions certora/stata/conf/verifyERC4626.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"files": [
"certora/stata/harness/StataTokenV2Harness.sol",
"certora/stata/harness/pool/SymbolicLendingPool.sol",
"certora/stata/harness/rewards/RewardsControllerHarness.sol",
"certora/stata/harness/rewards/TransferStrategyHarness.sol",
"certora/stata/harness/tokens/DummyERC20_aTokenUnderlying.sol",
"certora/stata/harness/tokens/DummyERC20_rewardToken.sol",
"certora/stata/munged/src/core/instances/ATokenInstance.sol",
],
"link": [
"SymbolicLendingPool:aToken=ATokenInstance",
"SymbolicLendingPool:underlyingToken=DummyERC20_aTokenUnderlying",
"TransferStrategyHarness:INCENTIVES_CONTROLLER=RewardsControllerHarness",
"TransferStrategyHarness:REWARD=DummyERC20_rewardToken",
"ATokenInstance:POOL=SymbolicLendingPool",
"ATokenInstance:_incentivesController=RewardsControllerHarness",
"ATokenInstance:_underlyingAsset=DummyERC20_aTokenUnderlying",
"StataTokenV2Harness:INCENTIVES_CONTROLLER=RewardsControllerHarness",
"StataTokenV2Harness:POOL=SymbolicLendingPool",
"StataTokenV2Harness:_reward_A=DummyERC20_rewardToken"
],
"packages": [
"aave-v3-core/=certora/stata/munged/src/core",
"aave-v3-periphery/=certora/stata/munged/src/periphery",
"solidity-utils/=certora/stata/munged/lib/solidity-utils/src",
"forge-std/=certora/stata/munged/lib/forge-std/src",
"openzeppelin-contracts-upgradeable/=certora/stata/munged/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable",
"openzeppelin-contracts/=certora/stata/munged/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts",
"@openzeppelin/contracts/=certora/stata/munged/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts",
],
"verify":"StataTokenV2Harness:certora/stata/specs/erc4626/erc4626.spec",
"solc": "solc8.20",
"msg": "ERC4626 properties",
"optimistic_loop": true,
"smt_timeout": "3600",
"loop_iter": "1",
"optimistic_hashing": true,
"build_cache": true,
}
Loading
Loading