Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we git-ignore this file? as it's automatically generated

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it was generated using forge bind-json, it is done once and not needed to be automatic or re-created as long as new types are not introduced or the current ones modified

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 _getBuyTypedDataHash(
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 _getSellTypedDataHash(
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