Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into refactor/move-adding-…
Browse files Browse the repository at this point in the history
…to-collateral-list
  • Loading branch information
pakim249CAL committed Jan 13, 2023
2 parents aa604e8 + 21bb683 commit 95901e4
Show file tree
Hide file tree
Showing 46 changed files with 1,211 additions and 547 deletions.
14 changes: 13 additions & 1 deletion .github/actions/forge-test/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,19 @@ runs:
key: ${{ github.base_ref || github.ref_name }}-forge-test-${{ inputs.network }} # always keep compiled contracts from base branch

- name: Run tests
run: make test
run: make test-unit
shell: bash
env:
NETWORK: ${{ inputs.network }}

- name: Run tests
run: make test-internal
shell: bash
env:
NETWORK: ${{ inputs.network }}

- name: Run tests
run: make test-integration
shell: bash
env:
NETWORK: ${{ inputs.network }}
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ node_modules/

# IDE
.vscode

# coverage
coverage
lcov.info
21 changes: 21 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,33 @@ install:
contracts:
FOUNDRY_TEST=/dev/null forge build --via-ir --sizes --force


test:
forge test -vvv

test-unit:
@FOUNDRY_PROFILE=test-unit make test

test-internal:
@FOUNDRY_PROFILE=test-internal make test

test-integration:
@FOUNDRY_PROFILE=test-integration make test


test-%:
@FOUNDRY_MATCH_TEST=$* make test

test-unit-%:
@FOUNDRY_MATCH_TEST=$* make test-unit

test-internal-%:
@FOUNDRY_MATCH_TEST=$* make test-internal

test-integration-%:
@FOUNDRY_MATCH_TEST=$* make test-integration


coverage:
forge coverage --report lcov
lcov --remove lcov.info -o lcov.info "test/*"
Expand Down
2 changes: 1 addition & 1 deletion config/avalanche-mainnet.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"usesRpcPrefix": false,
"rpc": "https://api.avax.network/ext/bc/C/rpc",
"rpc": "https://avalanche-mainnet.infura.io/v3/4d3eaa358c4841e78cb1032d4f6d8726",
"chainId": 43114,
"testBlock": 24437213,
"testMarkets": [
Expand Down
23 changes: 21 additions & 2 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
[profile.default]
fs_permissions = [{ access = "read", path = "./"}]
names = true
sizes = true
libs = ["node_modules", "lib"]
fs_permissions = [{ access = "read", path = "./config/"}]

[fuzz]
runs = 16

[profile.ci.fuzz]

[profile.test-unit]
test = "test/unit/"

[profile.test-unit.fuzz]
runs = 4096


[profile.test-internal]
test = "test/internal/"

[profile.test-internal.fuzz]
runs = 128


[profile.test-integration]
test = "test/integration/"

[profile.test-integration.fuzz]
runs = 512


# See more config options https://github.com/foundry-rs/foundry/tree/master/config
3 changes: 3 additions & 0 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
src/=src/
test/=test/

@forge-std/=lib/forge-std/src/
@ds-test/=lib/forge-std/lib/ds-test/src/

Expand Down
42 changes: 20 additions & 22 deletions src/Morpho.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import {IMorpho} from "./interfaces/IMorpho.sol";
import {IPositionsManager} from "./interfaces/IPositionsManager.sol";
import {IRewardsController} from "@aave/periphery-v3/contracts/rewards/interfaces/IRewardsController.sol";

import {Types} from "./libraries/Types.sol";
import {Events} from "./libraries/Events.sol";
import {Errors} from "./libraries/Errors.sol";
import {Constants} from "./libraries/Constants.sol";

import {Permit2Lib} from "./libraries/Permit2Lib.sol";
import {DelegateCall} from "@morpho-utils/DelegateCall.sol";
import {ERC20, SafeTransferLib} from "@solmate/utils/SafeTransferLib.sol";

Expand All @@ -16,6 +19,7 @@ import {MorphoGetters} from "./MorphoGetters.sol";
import {MorphoSetters} from "./MorphoSetters.sol";

contract Morpho is IMorpho, MorphoGetters, MorphoSetters {
using Permit2Lib for ERC20;
using DelegateCall for address;
using SafeTransferLib for ERC20;

Expand All @@ -38,11 +42,9 @@ contract Morpho is IMorpho, MorphoGetters, MorphoSetters {
address onBehalf,
uint256 maxLoops,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
Types.Signature calldata signature
) external returns (uint256 supplied) {
ERC20(underlying).permit(msg.sender, address(this), amount, deadline, v, r, s);
ERC20(underlying).permit2(msg.sender, address(this), amount, deadline, signature.v, signature.r, signature.s);
return _supply(underlying, amount, msg.sender, onBehalf, maxLoops);
}

Expand All @@ -58,11 +60,9 @@ contract Morpho is IMorpho, MorphoGetters, MorphoSetters {
uint256 amount,
address onBehalf,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
Types.Signature calldata signature
) external returns (uint256 supplied) {
ERC20(underlying).permit(msg.sender, address(this), amount, deadline, v, r, s);
ERC20(underlying).permit2(msg.sender, address(this), amount, deadline, signature.v, signature.r, signature.s);
return _supplyCollateral(underlying, amount, msg.sender, onBehalf);
}

Expand All @@ -86,11 +86,9 @@ contract Morpho is IMorpho, MorphoGetters, MorphoSetters {
address onBehalf,
uint256 maxLoops,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
Types.Signature calldata signature
) external returns (uint256 repaid) {
ERC20(underlying).permit(msg.sender, address(this), amount, deadline, v, r, s);
ERC20(underlying).permit2(msg.sender, address(this), amount, deadline, signature.v, signature.r, signature.s);
return _repay(underlying, amount, msg.sender, onBehalf, maxLoops);
}

Expand Down Expand Up @@ -125,21 +123,21 @@ contract Morpho is IMorpho, MorphoGetters, MorphoSetters {
bool isAllowed,
uint256 nonce,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
Types.Signature calldata signature
) external {
if (uint256(s) > Constants.MAX_VALID_ECDSA_S) revert Errors.InvalidValueS();
if (uint256(signature.s) > Constants.MAX_VALID_ECDSA_S) revert Errors.InvalidValueS();
// v ∈ {27, 28} (source: https://ethereum.github.io/yellowpaper/paper.pdf #308)
if (v != 27 && v != 28) revert Errors.InvalidValueV();
if (signature.v != 27 && signature.v != 28) revert Errors.InvalidValueV();

bytes32 structHash =
keccak256(abi.encode(Constants.AUTHORIZATION_TYPEHASH, owner, manager, isAllowed, nonce, deadline));
bytes32 digest = keccak256(abi.encodePacked("\x19\x01", _computeDomainSeparator(), structHash));
address signatory = ecrecover(digest, v, r, s);
if (signatory == address(0)) revert Errors.InvalidSignatory();
if (owner != signatory) revert Errors.InvalidSignatory();
keccak256(abi.encode(Constants.EIP712_AUTHORIZATION_TYPEHASH, owner, manager, isAllowed, nonce, deadline));
bytes32 digest = _hashEIP712TypedData(structHash);
address signatory = ecrecover(digest, signature.v, signature.r, signature.s);

if (signatory == address(0) || owner != signatory) revert Errors.InvalidSignatory();
if (nonce != _userNonce[signatory]++) revert Errors.InvalidNonce();
if (block.timestamp >= deadline) revert Errors.SignatureExpired();

_approveManager(signatory, manager, isAllowed);
}

Expand Down
2 changes: 1 addition & 1 deletion src/MorphoGetters.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ abstract contract MorphoGetters is IMorphoGetters, MorphoInternal {
}

function DOMAIN_SEPARATOR() external view returns (bytes32) {
return _computeDomainSeparator();
return _DOMAIN_SEPARATOR;
}

function market(address underlying) external view returns (Types.Market memory) {
Expand Down
Loading

0 comments on commit 95901e4

Please sign in to comment.