Skip to content

Commit

Permalink
πŸ‘” contracts: allow setting operation expiry on issuer checker
Browse files Browse the repository at this point in the history
  • Loading branch information
itofarina committed Dec 30, 2024
1 parent aafcc2c commit 7edfecf
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 13 deletions.
15 changes: 9 additions & 6 deletions contracts/.gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ExaAccountFactoryTest:testFuzz_createAccount_EOAOwners(uint256,address[63]) (runs: 256, ΞΌ: 3621366, ~: 3460632)
ExaPluginTest:testFork_crossRepay_repays() (gas: 19666737)
ExaPluginTest:testFork_debitCollateral_collects() (gas: 19756315)
ExaPluginTest:testFork_swap_swaps() (gas: 16912274)
ExaPluginTest:testFork_crossRepay_repays() (gas: 19667625)
ExaPluginTest:testFork_debitCollateral_collects() (gas: 19757203)
ExaPluginTest:testFork_swap_swaps() (gas: 16913033)
ExaPluginTest:test_borrowAtMaturity_reverts_withUnauthorized_whenReceiverNotCollector() (gas: 408975)
ExaPluginTest:test_borrow_reverts_withUnauthorized_whenReceiverNotCollector() (gas: 408553)
ExaPluginTest:test_collectCredit_collects() (gas: 921083)
Expand Down Expand Up @@ -70,9 +70,12 @@ ExaPluginTest:test_withdraw_reverts_whenWrongReceiver() (gas: 308405)
ExaPluginTest:test_withdraw_transfersAsset_asKeeper() (gas: 820334)
ExaPluginTest:test_withdraw_transfersAsset_asOwner() (gas: 819025)
InstallmentsPreviewerTest:test_preview_returns() (gas: 135598)
IssuerCheckerTest:test_setIssuer_emits_IssuerSet() (gas: 41782)
IssuerCheckerTest:test_setIssuer_reverts_whenNotAdmin() (gas: 37070)
IssuerCheckerTest:test_setIssuer_reverts_whenZeroAddress() (gas: 35449)
IssuerCheckerTest:test_setIssuer_emits_IssuerSet() (gas: 41827)
IssuerCheckerTest:test_setIssuer_reverts_whenNotAdmin() (gas: 37115)
IssuerCheckerTest:test_setIssuer_reverts_whenZeroAddress() (gas: 35472)
IssuerCheckerTest:test_setOperationExpiry_emits_OperationExpirySet() (gas: 46845)
IssuerCheckerTest:test_setOperationExpiry_reverts_whenNotAdmin() (gas: 39005)
IssuerCheckerTest:test_setOperationExpiry_reverts_whenZeroValue() (gas: 37471)
MockSwapperTest:test_swapExactAmountIn_swaps() (gas: 220530)
MockSwapperTest:test_swapExactAmountOut_swaps() (gas: 220657)
RefunderTest:test_refund_refunds() (gas: 242371)
Expand Down
3 changes: 2 additions & 1 deletion contracts/deploy.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@
"11155420": "0x7AF28c94757628378E625AD8B6f51f2Ac1391eda",
"default": "0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE"
}
}
},
"issuerChecker": { "operationExpiry": 54000 }
}
9 changes: 7 additions & 2 deletions contracts/script/IssuerChecker.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ pragma solidity ^0.8.0;

import { IssuerChecker } from "../src/IssuerChecker.sol";

import { BaseScript } from "./Base.s.sol";
import { BaseScript, stdJson } from "./Base.s.sol";

contract DeployIssuerChecker is BaseScript {
using stdJson for string;

IssuerChecker public issuerChecker;

function run() external {
string memory deploy = vm.readFile("deploy.json");
vm.broadcast(acct("deployer"));
issuerChecker = new IssuerChecker(acct("admin"), acct("issuer"));
issuerChecker = new IssuerChecker(
acct("admin"), acct("issuer"), abi.decode(deploy.parseRaw(".issuerChecker.operationExpiry"), (uint256))
);
}
}
17 changes: 16 additions & 1 deletion contracts/src/IssuerChecker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ contract IssuerChecker is AccessControl, EIP712 {

address public issuer;
mapping(address account => bytes32 hash) public issuerOperations;
uint256 public operationExpiry;

constructor(address owner, address issuer_) {
constructor(address owner, address issuer_, uint256 operationExpiry_) {
_grantRole(DEFAULT_ADMIN_ROLE, owner);
_setIssuer(issuer_);
_setOperationExpiry(operationExpiry_);
}

function checkIssuer(address account, uint256 amount, uint256 timestamp, bytes calldata signature) external {
Expand All @@ -46,6 +48,10 @@ contract IssuerChecker is AccessControl, EIP712 {
_setIssuer(issuer_);
}

function setOperationExpiry(uint256 operationExpiry_) external onlyRole(DEFAULT_ADMIN_ROLE) {
_setOperationExpiry(operationExpiry_);
}

// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() public view returns (bytes32) {
return _domainSeparator();
Expand All @@ -61,11 +67,20 @@ contract IssuerChecker is AccessControl, EIP712 {
issuer = issuer_;
emit IssuerSet(issuer_, msg.sender);
}

function _setOperationExpiry(uint256 operationExpiry_) internal {
if (operationExpiry_ == 0) revert InvalidOperationExpiry();
operationExpiry = operationExpiry_;
emit OperationExpirySet(operationExpiry_, msg.sender);
}
}

event IssuerSet(address indexed issuer, address indexed account);

event OperationExpirySet(uint256 operationExpiry, address indexed account);

error Expired();
error InvalidOperationExpiry();
error Timelocked();
error Unauthorized();
error ZeroAddress();
37 changes: 35 additions & 2 deletions contracts/test/IssuerChecker.t.sol
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

import { IssuerChecker, IssuerSet, ZeroAddress } from "../src/IssuerChecker.sol";
import {
InvalidOperationExpiry, IssuerChecker, IssuerSet, OperationExpirySet, ZeroAddress
} from "../src/IssuerChecker.sol";
import { ForkTest } from "./Fork.t.sol";
import { IAccessControl } from "openzeppelin-contracts/contracts/access/IAccessControl.sol";

contract IssuerCheckerTest is ForkTest {
IssuerChecker internal issuerChecker;
uint256 internal operationExpiry = 10 minutes;

function setUp() external {
issuerChecker = new IssuerChecker(address(this), address(this));
issuerChecker = new IssuerChecker(address(this), address(this), operationExpiry);
}

// solhint-disable func-name-mixedcase
Expand Down Expand Up @@ -43,5 +46,35 @@ contract IssuerCheckerTest is ForkTest {
assertEq(issuerChecker.issuer(), address(this));
}

function test_setOperationExpiry_emits_OperationExpirySet() external {
assertEq(issuerChecker.operationExpiry(), operationExpiry);
uint256 newOperationExpiry = 20 minutes;
vm.expectEmit(true, true, true, true, address(issuerChecker));
emit OperationExpirySet(newOperationExpiry, address(this));
issuerChecker.setOperationExpiry(newOperationExpiry);

assertEq(issuerChecker.operationExpiry(), newOperationExpiry);
}

function test_setOperationExpiry_reverts_whenZeroValue() external {
vm.expectRevert(InvalidOperationExpiry.selector);
issuerChecker.setOperationExpiry(0);

assertEq(issuerChecker.operationExpiry(), operationExpiry);
}

function test_setOperationExpiry_reverts_whenNotAdmin() external {
address notAdmin = address(0x123);
vm.startPrank(notAdmin);
vm.expectRevert(
abi.encodeWithSelector(
IAccessControl.AccessControlUnauthorizedAccount.selector, notAdmin, issuerChecker.DEFAULT_ADMIN_ROLE()
)
);
issuerChecker.setOperationExpiry(20 minutes);

assertEq(issuerChecker.operationExpiry(), operationExpiry);
}

// solhint-enable func-name-mixedcase
}
2 changes: 1 addition & 1 deletion contracts/test/Refunder.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ contract RefunderTest is ForkTest {
(keeper, keeperKey) = makeAddrAndKey("keeper");
(issuer, issuerKey) = makeAddrAndKey("issuer");

issuerChecker = new IssuerChecker(address(this), issuer);
issuerChecker = new IssuerChecker(address(this), issuer, 15 minutes);

refunder = new Refunder(address(this), exaUSDC, issuerChecker, keeper);

Expand Down

0 comments on commit 7edfecf

Please sign in to comment.