After the config preparation, I created a test folder and test file in this directory contracts/test/AaveDIVAWrapperFoundryTest.t.sol
pragma solidity 0.8.26;
import {Test, console} from "forge-std/Test.sol";
import {AaveDIVAWrapper} from "../src/AaveDIVAWrapper.sol";
import {IAaveDIVAWrapper} from "../src/interfaces/IAaveDIVAWrapper.sol";
import {IAave} from "../src/interfaces/IAave.sol";
import {IDIVA} from "../src/interfaces/IDIVA.sol";
import {ERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
contract AaveDIVAWrapperFoundryTest is Test {
AaveDIVAWrapper public aaveDIVAWrapper;
AaveDIVAWrapper public aaveDIVAWrapperETH;
IDIVA public diva;
IAave public aave;
ERC20 public collateralTokenContract;
address public owner;
address public dataProvider;
address public impersonatedSigner;
uint8 public collateralTokenDecimals;
uint8 public dummyTokenDecimals = 18;
* Addresses on Arbutrum Mainnet
*
* DIVA arbitrumMain: "0x2C9c47E7d254e493f02acfB410864b9a86c28e1D"
* AaveV3 arbitrumMain: "0x794a61358D6845594F94dc1DB02A252b5b4814aD"
*
* collateralTokens
* USDC:
* address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831"
* holder: "0xE6fCC492FB5eA091bDBE2E1a9f163e5039F144BC"
*
* unsupportedToken
* address: "0x7f9FBf9bDd3F4105C478b996B648FE6e828a1e98"
* description: "APE token (not supported on Aave)"
*
*/
address public constant DIVA_ADDRESS = 0x2C9c47E7d254e493f02acfB410864b9a86c28e1D;
address public constant AAVE_ADDRESS = 0x794a61358D6845594F94dc1DB02A252b5b4814aD;
address public constant COLLATERAL_TOKEN = 0xaf88d065e77c8cC2239327C5EDb3A432268e5831;
address public constant COLLATERAL_TOKEN_HOLDER = 0x2Df1c51E09aECF9cacB7bc98cB1742757f163dF7;
address public constant collateralTokenEthereum = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
address public constant collateralTokenEthereumHolder = 0x37305B1cD40574E4C5Ce33f8e8306Be057fD7341;
function setUp() public {
vm.createSelectFork(vm.rpcUrl("arbitrum"));
owner = makeAddr("owner");
dataProvider = makeAddr("dataProvider");
vm.startPrank(COLLATERAL_TOKEN_HOLDER);
impersonatedSigner = COLLATERAL_TOKEN_HOLDER;
collateralTokenContract = ERC20(COLLATERAL_TOKEN);
collateralTokenDecimals = collateralTokenContract.decimals();
uint256 balance = collateralTokenContract.balanceOf(impersonatedSigner);
console.log("Balance: ", balance);
assertGt(balance, 1000 * (10 ** collateralTokenDecimals), "Insufficient balance for testing");
vm.stopPrank();
aaveDIVAWrapper = new AaveDIVAWrapper(DIVA_ADDRESS, AAVE_ADDRESS, owner);
diva = IDIVA(DIVA_ADDRESS);
aave = IAave(AAVE_ADDRESS);
vm.startPrank(impersonatedSigner);
collateralTokenContract.approve(address(aaveDIVAWrapper), type(uint256).max);
collateralTokenContract.approve(address(diva), type(uint256).max);
collateralTokenContract.approve(address(aave), type(uint256).max);
vm.stopPrank();
vm.createSelectFork(vm.rpcUrl("ethereum"));
address divaETH = 0x2C9c47E7d254e493f02acfB410864b9a86c28e1D;
address aaveETH = 0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2;
collateralTokenContract = ERC20(collateralTokenEthereum);
aaveDIVAWrapperETH = new AaveDIVAWrapper(divaETH, aaveETH, owner);
vm.startPrank(collateralTokenEthereumHolder);
collateralTokenContract.approve(address(aaveDIVAWrapperETH), type(uint256).max);
collateralTokenContract.approve(divaETH, type(uint256).max);
collateralTokenContract.approve(aaveETH, type(uint256).max);
vm.stopPrank();
}
function testHashCollisionWhenRegisteringCollateralToken() public {
vm.selectFork(0);
vm.prank(owner);
aaveDIVAWrapper.registerCollateralToken(COLLATERAL_TOKEN);
ERC20 wTokenArb = ERC20(aaveDIVAWrapper.getWToken(COLLATERAL_TOKEN));
console.log("Collision 1: %s", wTokenArb.symbol());
console.log("Hash 1: %s", toHexString(keccak256(abi.encodePacked(wTokenArb.name()))));
vm.selectFork(1);
vm.prank(owner);
aaveDIVAWrapperETH.registerCollateralToken(collateralTokenEthereum);
ERC20 wTokenEth = ERC20(aaveDIVAWrapperETH.getWToken(collateralTokenEthereum));
console.log("Collision 2: %s", wTokenEth.symbol());
console.log("Hash 2: %s", toHexString(keccak256(abi.encodePacked(wTokenEth.name()))));
}
function toHexString(bytes32 data) internal pure returns (string memory) {
bytes memory hexChars = "0123456789abcdef";
bytes memory str = new bytes(64);
for (uint256 i = 0; i < 32; i++) {
str[i * 2] = hexChars[uint8(data[i] >> 4)];
str[1 + i * 2] = hexChars[uint8(data[i] & 0x0f)];
}
return string(str);
}
}
function _registerCollateralToken(address _collateralToken) internal returns (address) {
if (_collateralTokenToWToken[_collateralToken] != address(0)) {
revert CollateralTokenAlreadyRegistered();
}
address _aToken = _getAToken(_collateralToken);
if (_aToken == address(0)) {
revert UnsupportedCollateralToken();
}
IERC20Metadata _collateralTokenContract = IERC20Metadata(_collateralToken);
WToken _wTokenContract = new WToken(
- string(abi.encodePacked("w", _collateralTokenContract.symbol())),
+ string(abi.encodePacked("w", IERC20Metadata(_aToken).symbol())),
_collateralTokenContract.decimals(),
address(this) // wToken owner
);
address _wToken = address(_wTokenContract);
_collateralTokenToWToken[_collateralToken] = _wToken;
_wTokenToCollateralToken[_wToken] = _collateralToken;
_wTokenContract.approve(_diva, type(uint256).max);
_collateralTokenContract.approve(_aaveV3Pool, type(uint256).max);
emit CollateralTokenRegistered(_collateralToken, _wToken);
return _wToken;
}