Skip to content
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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "lib/aave-v3-origin"]
path = lib/aave-v3-origin
url = https://github.com/aave-dao/aave-v3-origin
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
8 changes: 8 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ test = 'tests'
script = 'scripts'
cache_path = 'cache'
libs = ['node_modules', 'lib']
fs_permissions = [{ access = "read", path = "tests/mocks/JsonBindings.sol" }]
ffi = true
evm_version = 'paris'
solc_version = '0.8.22'
Expand All @@ -19,3 +20,10 @@ ignored_warnings_from = [
]
optimizer = true
optimizer_runs = 200

[bind_json]
out = "tests/mocks/JsonBindings.sol"
include = ["tests/helpers/EIP712Types.sol"]

[lint]
ignore = ["tests/mocks/JsonBindings.sol"]
1 change: 1 addition & 0 deletions lib/forge-std
Submodule forge-std added at 8bbcf6
2 changes: 1 addition & 1 deletion remappings.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
forge-std/=lib/aave-v3-origin/lib/forge-std/src/
forge-std/=lib/forge-std/src/
aave-v3-origin/=lib/aave-v3-origin/src/
aave-v3-origin-tests/=lib/aave-v3-origin/tests/
solidity-utils/=lib/aave-v3-origin/lib/solidity-utils/src/
32 changes: 20 additions & 12 deletions src/contracts/facilitators/gsm/Gsm.sol
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,16 @@ contract Gsm is AccessControl, VersionedInitializable, EIP712, IGsm {
bytes calldata signature
) external notFrozen notSeized returns (uint256, uint256) {
require(deadline >= block.timestamp, 'SIGNATURE_DEADLINE_EXPIRED');
bytes32 digest = keccak256(
abi.encode(
'\x19\x01',
_domainSeparatorV4(),
BUY_ASSET_WITH_SIG_TYPEHASH,
abi.encode(originator, minAmount, receiver, nonces[originator]++, deadline)
bytes32 digest = _hashTypedDataV4(
keccak256(
abi.encode(
BUY_ASSET_WITH_SIG_TYPEHASH,
originator,
minAmount,
receiver,
nonces[originator]++,
deadline
)
)
);
require(
Expand Down Expand Up @@ -175,12 +179,16 @@ contract Gsm is AccessControl, VersionedInitializable, EIP712, IGsm {
bytes calldata signature
) external notFrozen notSeized returns (uint256, uint256) {
require(deadline >= block.timestamp, 'SIGNATURE_DEADLINE_EXPIRED');
bytes32 digest = keccak256(
abi.encode(
'\x19\x01',
_domainSeparatorV4(),
SELL_ASSET_WITH_SIG_TYPEHASH,
abi.encode(originator, maxAmount, receiver, nonces[originator]++, deadline)
bytes32 digest = _hashTypedDataV4(
keccak256(
abi.encode(
SELL_ASSET_WITH_SIG_TYPEHASH,
originator,
maxAmount,
receiver,
nonces[originator]++,
deadline
)
)
);
require(
Expand Down
22 changes: 22 additions & 0 deletions tests/helpers/EIP712Types.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

library EIP712Types {
//BuyAssetWithSig(address originator,uint256 minAmount,address receiver,uint256 nonce,uint256 deadline)
struct BuyAssetWithSig {
address originator;
uint256 minAmount;
address receiver;
uint256 nonce;
uint256 deadline;
}

//SellAssetWithSig(address originator,uint256 maxAmount,address receiver,uint256 nonce,uint256 deadline)
struct SellAssetWithSig {
address originator;
uint256 maxAmount;
address receiver;
uint256 nonce;
uint256 deadline;
}
}
131 changes: 131 additions & 0 deletions tests/mocks/JsonBindings.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// Automatically generated by forge bind-json.
pragma solidity >=0.6.2 <0.9.0;
pragma experimental ABIEncoderV2;

import {EIP712Types} from 'tests/helpers/EIP712Types.sol';

interface Vm {
function parseJsonTypeArray(
string calldata json,
string calldata key,
string calldata typeDescription
) external pure returns (bytes memory);

function parseJsonType(
string calldata json,
string calldata typeDescription
) external pure returns (bytes memory);

function parseJsonType(
string calldata json,
string calldata key,
string calldata typeDescription
) external pure returns (bytes memory);

function serializeJsonType(
string calldata typeDescription,
bytes memory value
) external pure returns (string memory json);

function serializeJsonType(
string calldata objectKey,
string calldata valueKey,
string calldata typeDescription,
bytes memory value
) external returns (string memory json);
}

library JsonBindings {
Vm constant vm = Vm(address(uint160(uint256(keccak256('hevm cheat code')))));

// prettier-ignore
string constant schema_BuyAssetWithSig = "BuyAssetWithSig(address originator,uint256 minAmount,address receiver,uint256 nonce,uint256 deadline)";
// prettier-ignore
string constant schema_SellAssetWithSig = "SellAssetWithSig(address originator,uint256 maxAmount,address receiver,uint256 nonce,uint256 deadline)";

function serialize(
EIP712Types.BuyAssetWithSig memory value
) internal pure returns (string memory) {
return vm.serializeJsonType(schema_BuyAssetWithSig, abi.encode(value));
}

function serialize(
EIP712Types.BuyAssetWithSig memory value,
string memory objectKey,
string memory valueKey
) internal returns (string memory) {
return vm.serializeJsonType(objectKey, valueKey, schema_BuyAssetWithSig, abi.encode(value));
}

function deserializeBuyAssetWithSig(
string memory json
) public pure returns (EIP712Types.BuyAssetWithSig memory) {
return
abi.decode(vm.parseJsonType(json, schema_BuyAssetWithSig), (EIP712Types.BuyAssetWithSig));
}

function deserializeBuyAssetWithSig(
string memory json,
string memory path
) public pure returns (EIP712Types.BuyAssetWithSig memory) {
return
abi.decode(
vm.parseJsonType(json, path, schema_BuyAssetWithSig),
(EIP712Types.BuyAssetWithSig)
);
}

function deserializeBuyAssetWithSigArray(
string memory json,
string memory path
) public pure returns (EIP712Types.BuyAssetWithSig[] memory) {
return
abi.decode(
vm.parseJsonTypeArray(json, path, schema_BuyAssetWithSig),
(EIP712Types.BuyAssetWithSig[])
);
}

function serialize(
EIP712Types.SellAssetWithSig memory value
) internal pure returns (string memory) {
return vm.serializeJsonType(schema_SellAssetWithSig, abi.encode(value));
}

function serialize(
EIP712Types.SellAssetWithSig memory value,
string memory objectKey,
string memory valueKey
) internal returns (string memory) {
return vm.serializeJsonType(objectKey, valueKey, schema_SellAssetWithSig, abi.encode(value));
}

function deserializeSellAssetWithSig(
string memory json
) public pure returns (EIP712Types.SellAssetWithSig memory) {
return
abi.decode(vm.parseJsonType(json, schema_SellAssetWithSig), (EIP712Types.SellAssetWithSig));
}

function deserializeSellAssetWithSig(
string memory json,
string memory path
) public pure returns (EIP712Types.SellAssetWithSig memory) {
return
abi.decode(
vm.parseJsonType(json, path, schema_SellAssetWithSig),
(EIP712Types.SellAssetWithSig)
);
}

function deserializeSellAssetWithSigArray(
string memory json,
string memory path
) public pure returns (EIP712Types.SellAssetWithSig[] memory) {
return
abi.decode(
vm.parseJsonTypeArray(json, path, schema_SellAssetWithSig),
(EIP712Types.SellAssetWithSig[])
);
}
}
28 changes: 28 additions & 0 deletions tests/unit/TestGhoBase.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ pragma solidity ^0.8.0;

import 'forge-std/Test.sol';
import 'forge-std/console2.sol';
import {Vm} from 'forge-std/Vm.sol';

// helpers
import {Constants} from '../helpers/Constants.sol';
import {DebtUtils} from '../helpers/DebtUtils.sol';
import {Events} from '../helpers/Events.sol';
import {AccessControlErrorsLib, OwnableErrorsLib} from '../helpers/ErrorsLib.sol';
import {EIP712Types} from '../helpers/EIP712Types.sol';

// generic libs
import {DataTypes} from 'aave-v3-origin/contracts/protocol/libraries/types/DataTypes.sol';
Expand Down Expand Up @@ -722,4 +724,30 @@ contract TestGhoBase is Test, Constants, Events {
);
(v, r, s) = vm.sign(ownerPk, outerHash);
}

function _getBuyAssetTypedDataHash(
EIP712Types.BuyAssetWithSig memory params
) internal view returns (bytes32) {
return
keccak256(
abi.encodePacked(
'\x19\x01',
GHO_GSM.DOMAIN_SEPARATOR(),
vm.eip712HashStruct('BuyAssetWithSig', abi.encode(params))
)
);
}

function _getSellAssetTypedDataHash(
EIP712Types.SellAssetWithSig memory params
) internal view returns (bytes32) {
return
keccak256(
abi.encodePacked(
'\x19\x01',
GHO_GSM.DOMAIN_SEPARATOR(),
vm.eip712HashStruct('SellAssetWithSig', abi.encode(params))
)
);
}
}
Loading
Loading