Skip to content

Commit

Permalink
Merge branch 'project-a' of github.com:bgd-labs/aave-v3-origin into p…
Browse files Browse the repository at this point in the history
…roject-a
  • Loading branch information
MichaelMorami committed Sep 10, 2024
2 parents 53edf5f + 5c63d4c commit 0c6f380
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 31 deletions.
2 changes: 1 addition & 1 deletion lib/solidity-utils
Submodule solidity-utils updated 29 files
+2 −2 .env.example
+7 −0 .github/workflows/merge-main.yml
+7 −0 .github/workflows/tests.yml
+1 −0 Makefile
+10 −9 foundry.toml
+0 −75 src-zksync/contracts/transparent-proxy/TransparentProxyFactoryZkSync.sol
+0 −22 src-zksync/contracts/transparent-proxy/interfaces/ITransparentProxyFactoryZkSync.sol
+1 −1 src/contracts/access-control/UpgradeableOwnableWithGuardian.sol
+4 −30 src/contracts/transparent-proxy/TransparentProxyFactory.sol
+19 −2 src/contracts/transparent-proxy/TransparentProxyFactoryBase.sol
+6 −6 src/contracts/utils/ChainHelpers.sol
+21 −0 src/contracts/utils/PermissionlessRescuable.sol
+4 −11 src/contracts/utils/Rescuable.sol
+32 −0 src/contracts/utils/RescuableBase.sol
+4 −0 src/contracts/utils/ScriptUtils.sol
+30 −0 src/contracts/utils/interfaces/IPermissionlessRescuable.sol
+3 −23 src/contracts/utils/interfaces/IRescuable.sol
+38 −0 src/contracts/utils/interfaces/IRescuableBase.sol
+4 −0 src/mocks/ERC20.sol
+127 −0 test/PermissionlessRescuable.t.sol
+10 −1 test/Rescuable.t.sol
+7 −0 test/Rescuable721.t.sol
+6 −6 test/UpgradeableOwnableWithGuardian.sol
+13 −0 zksync/script/DeployTransparentProxyFactoryZkSync.s.sol
+60 −0 zksync/src/contracts/transparent-proxy/TransparentProxyFactoryZkSync.sol
+10 −0 zksync/src/contracts/transparent-proxy/interfaces/ITransparentProxyFactoryZkSync.sol
+113 −0 zksync/src/contracts/utils/ScriptUtilsZkSync.sol
+10 −0 zksync/src/contracts/utils/interfaces/ICreate2Factory.sol
+5 −5 zksync/test/TransparentProxyFactoryZkSync.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
pragma solidity ^0.8.0;

import '../../interfaces/IMarketReportTypes.sol';
import {TransparentProxyFactory, ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/TransparentProxyFactory.sol';
import {ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/interfaces/ITransparentProxyFactory.sol';
import {TransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/TransparentProxyFactory.sol';
import {StataTokenV2} from 'aave-v3-periphery/contracts/static-a-token/StataTokenV2.sol';
import {StataTokenFactory} from 'aave-v3-periphery/contracts/static-a-token/StataTokenFactory.sol';
import {IErrors} from '../../interfaces/IErrors.sol';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ abstract contract ERC4626StataTokenUpgradeable is ERC4626Upgradeable, IERC4626St
}

///@inheritdoc IERC4626StataToken
function aToken() external view returns (IERC20) {
function aToken() public view returns (IERC20) {
ERC4626StataTokenStorage storage $ = _getERC4626StataTokenStorage();
return $._aToken;
}
Expand Down
46 changes: 39 additions & 7 deletions src/periphery/contracts/static-a-token/StataTokenV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
pragma solidity ^0.8.0;

import {ERC20Upgradeable, ERC20PermitUpgradeable} from 'openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20PermitUpgradeable.sol';
import {IERC20Metadata} from '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';
import {PausableUpgradeable} from 'openzeppelin-contracts-upgradeable/contracts/utils/PausableUpgradeable.sol';
import {IRescuable, Rescuable} from 'solidity-utils/contracts/utils/Rescuable.sol';
import {IPermissionlessRescuable, PermissionlessRescuable} from 'solidity-utils/contracts/utils/PermissionlessRescuable.sol';
import {IRescuableBase, RescuableBase} from 'solidity-utils/contracts/utils/RescuableBase.sol';
import {IERC20Permit} from '@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol';

import {IACLManager} from '../../../core/contracts/interfaces/IACLManager.sol';
import {ERC4626Upgradeable, ERC4626StataTokenUpgradeable, IPool} from './ERC4626StataTokenUpgradeable.sol';
import {ERC4626Upgradeable, ERC4626StataTokenUpgradeable, IPool, Math, IERC20} from './ERC4626StataTokenUpgradeable.sol';
import {ERC20AaveLMUpgradeable, IRewardsController} from './ERC20AaveLMUpgradeable.sol';
import {IStataTokenV2} from './interfaces/IStataTokenV2.sol';
import {IAToken} from './interfaces/IAToken.sol';

/**
* @title StataTokenV2
Expand All @@ -20,9 +24,11 @@ contract StataTokenV2 is
ERC20AaveLMUpgradeable,
ERC4626StataTokenUpgradeable,
PausableUpgradeable,
Rescuable,
PermissionlessRescuable,
IStataTokenV2
{
using Math for uint256;

constructor(
IPool pool,
IRewardsController rewardsController
Expand Down Expand Up @@ -53,17 +59,43 @@ contract StataTokenV2 is
else _unpause();
}

/// @inheritdoc IRescuable
function whoCanRescue() public view override returns (address) {
return POOL_ADDRESSES_PROVIDER.getACLAdmin();
/// @inheritdoc IPermissionlessRescuable
function whoShouldReceiveFunds() public view override returns (address) {
return IAToken(address(aToken())).RESERVE_TREASURY_ADDRESS();
}

/// @inheritdoc IRescuableBase
function maxRescue(
address asset
) public view override(IRescuableBase, RescuableBase) returns (uint256) {
IERC20 cachedAToken = aToken();
if (asset == address(cachedAToken)) {
uint256 requiredBacking = _convertToAssets(totalSupply(), Math.Rounding.Ceil);
uint256 balance = cachedAToken.balanceOf(address(this));
return balance > requiredBacking ? balance - requiredBacking : 0;
}
return type(uint256).max;
}

///@inheritdoc IStataTokenV2
function canPause(address actor) public view returns (bool) {
return IACLManager(POOL_ADDRESSES_PROVIDER.getACLManager()).isEmergencyAdmin(actor);
}

function decimals() public view override(ERC20Upgradeable, ERC4626Upgradeable) returns (uint8) {
///@inheritdoc IERC20Permit
function nonces(
address owner
) public view virtual override(ERC20PermitUpgradeable, IERC20Permit) returns (uint256) {
return super.nonces(owner);
}

///@inheritdoc IERC20Metadata
function decimals()
public
view
override(IERC20Metadata, ERC20Upgradeable, ERC4626Upgradeable)
returns (uint8)
{
/// @notice The initialization of ERC4626Upgradeable already assures that decimal are
/// the same as the underlying asset of the StataTokenV2, e.g. decimals of WETH for stataWETH
return ERC4626Upgradeable.decimals();
Expand Down
2 changes: 2 additions & 0 deletions src/periphery/contracts/static-a-token/interfaces/IAToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ interface IAToken {

function UNDERLYING_ASSET_ADDRESS() external view returns (address);

function RESERVE_TREASURY_ADDRESS() external view returns (address);

/**
* @notice Returns the scaled total supply of the scaled balance token. Represents sum(debt/index)
* @return The scaled total supply
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ pragma solidity ^0.8.0;

import {IERC4626StataToken} from './IERC4626StataToken.sol';
import {IERC20AaveLM} from './IERC20AaveLM.sol';
import {IERC4626} from '@openzeppelin/contracts/interfaces/IERC4626.sol';
import {IERC20Permit} from '@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol';

interface IStataTokenV2 is IERC4626StataToken, IERC20AaveLM {
interface IStataTokenV2 is IERC4626, IERC20Permit, IERC4626StataToken, IERC20AaveLM {
/**
* @notice Checks if the passed actor is permissioned emergency admin.
* @param actor The reward to claim
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ contract ERC4626StataTokenUpgradeableTest is TestnetProcedures {
assertEq(erc4626Upgradeable.previewRedeem(shares), assets);
}

function test_totalAssets_shouldbeZeroOnZeroSupply() external view {
assertEq(erc4626Upgradeable.totalAssets(), 0);
}

// ### DEPOSIT TESTS ###
function test_depositATokens(uint128 assets, address receiver) public {
_validateReceiver(receiver);
Expand Down
44 changes: 25 additions & 19 deletions tests/periphery/static-a-token/StataTokenV2Rescuable.sol
Original file line number Diff line number Diff line change
@@ -1,31 +1,37 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.10;

import {IRescuable} from 'solidity-utils/contracts/utils/Rescuable.sol';
import {IAToken} from '../../../src/periphery/contracts/static-a-token/StataTokenV2.sol';
import {BaseTest} from './TestBase.sol';

contract StataTokenV2RescuableTest is BaseTest {
function test_whoCanRescue() external view {
assertEq(IRescuable(address(stataTokenV2)).whoCanRescue(), poolAdmin);
}
event ERC20Rescued(
address indexed caller,
address indexed token,
address indexed to,
uint256 amount
);

function test_rescuable_shouldRevertForInvalidCaller() external {
function test_rescuable_shouldTransferAssetsToCollector() external {
deal(tokenList.usdx, address(stataTokenV2), 1 ether);
vm.expectRevert('ONLY_RESCUE_GUARDIAN');
IRescuable(address(stataTokenV2)).emergencyTokenTransfer(
tokenList.usdx,
address(this),
1 ether
);
stataTokenV2.emergencyTokenTransfer(tokenList.usdx, 1 ether);
}

function test_rescuable_shouldSuceedForOwner() external {
deal(tokenList.usdx, address(stataTokenV2), 1 ether);
vm.startPrank(poolAdmin);
IRescuable(address(stataTokenV2)).emergencyTokenTransfer(
tokenList.usdx,
address(this),
1 ether
);
function test_rescuable_shouldWorkForAToken() external {
_fundAToken(1 ether, address(stataTokenV2));
stataTokenV2.emergencyTokenTransfer(aToken, 1 ether);
}

function test_rescuable_shouldNotCauseInsolvency(uint256 donation, uint256 stake) external {
vm.assume(donation != 0 && donation <= type(uint96).max);
vm.assume(stake != 0 && stake <= type(uint96).max);
_fundAToken(donation, address(stataTokenV2));
_fund4626(stake, address(this));

address treasury = IAToken(aToken).RESERVE_TREASURY_ADDRESS();

vm.expectEmit(true, true, true, true);
emit ERC20Rescued(address(this), aToken, treasury, donation);
stataTokenV2.emergencyTokenTransfer(aToken, donation + stake);
}
}
2 changes: 1 addition & 1 deletion tests/periphery/static-a-token/TestBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity ^0.8.10;

import {IERC20Metadata, IERC20} from 'openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol';
import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol';
import {ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/TransparentProxyFactory.sol';
import {ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/interfaces/ITransparentProxyFactory.sol';
import {StataTokenFactory} from '../../../src/periphery/contracts/static-a-token/StataTokenFactory.sol';
import {StataTokenV2} from '../../../src/periphery/contracts/static-a-token/StataTokenV2.sol';
import {IERC20AaveLM} from '../../../src/periphery/contracts/static-a-token/interfaces/IERC20AaveLM.sol';
Expand Down

0 comments on commit 0c6f380

Please sign in to comment.