Skip to content

Commit c439e5b

Browse files
authored
S4 gas optimizations (#160)
* fix: use custom error for unsupported ERC20 * fix: reuse parentId
1 parent d2ef1d7 commit c439e5b

File tree

6 files changed

+28
-15
lines changed

6 files changed

+28
-15
lines changed

src/facets/TokenizedVaultIOFacet.sol

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { LibObject } from "../libs/LibObject.sol";
99
import { LibConstants as LC } from "../libs/LibConstants.sol";
1010
import { LibACL } from "../libs/LibACL.sol";
1111
import { LibHelpers } from "../libs/LibHelpers.sol";
12-
import { ExternalWithdrawInvalidReceiver } from "../shared/CustomErrors.sol";
12+
import { ExternalWithdrawInvalidReceiver, InvalidERC20Token } from "../shared/CustomErrors.sol";
1313
import { ReentrancyGuard } from "../utils/ReentrancyGuard.sol";
1414

1515
/**
@@ -29,8 +29,10 @@ contract TokenizedVaultIOFacet is Modifiers, ReentrancyGuard {
2929
address _externalTokenAddress,
3030
uint256 _amount
3131
) external notLocked nonReentrant assertPrivilege(LibObject._getParentFromAddress(msg.sender), LC.GROUP_EXTERNAL_DEPOSIT) {
32-
// a user can only deposit an approved external ERC20 token
33-
require(LibAdmin._isSupportedExternalTokenAddress(_externalTokenAddress), "extDeposit: invalid ERC20 token");
32+
if (!LibAdmin._isSupportedExternalTokenAddress(_externalTokenAddress)) {
33+
revert InvalidERC20Token(_externalTokenAddress, "extDeposit");
34+
}
35+
3436
// a user can only deposit to their valid entity
3537
bytes32 entityId = LibObject._getParentFromAddress(msg.sender);
3638
require(LibEntity._isEntity(entityId), "extDeposit: invalid receiver");

src/facets/ZapFacet.sol

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
pragma solidity 0.8.20;
33

44
import { PermitSignature, OnboardingApproval } from "../shared/FreeStructs.sol";
5+
import { InvalidERC20Token } from "../shared/CustomErrors.sol";
56
import { Modifiers } from "../shared/Modifiers.sol";
67
import { LibTokenizedVaultIO } from "../libs/LibTokenizedVaultIO.sol";
78
import { LibACL } from "../libs/LibACL.sol";
@@ -33,15 +34,16 @@ contract ZapFacet is Modifiers, ReentrancyGuard {
3334
PermitSignature calldata _permitSignature,
3435
OnboardingApproval calldata _onboardingApproval
3536
) external notLocked nonReentrant {
36-
// Check if it's a supported ERC20 token
37-
require(LibAdmin._isSupportedExternalTokenAddress(_externalTokenAddress), "zapStake: invalid ERC20 token");
38-
39-
if (_onboardingApproval.entityId != 0 && LibObject._getParentFromAddress(msg.sender) != _onboardingApproval.entityId) {
40-
LibAdmin._onboardUserViaSignature(_onboardingApproval);
37+
if (!LibAdmin._isSupportedExternalTokenAddress(_externalTokenAddress)) {
38+
revert InvalidERC20Token(_externalTokenAddress, "zapStake");
4139
}
4240

4341
bytes32 parentId = LibObject._getParentFromAddress(msg.sender);
4442

43+
if (_onboardingApproval.entityId != 0 && parentId != _onboardingApproval.entityId) {
44+
LibAdmin._onboardUserViaSignature(_onboardingApproval);
45+
}
46+
4547
// Use permit to set allowance
4648
IERC20(_externalTokenAddress).permit(msg.sender, address(this), _amountToDeposit, _permitSignature.deadline, _permitSignature.v, _permitSignature.r, _permitSignature.s);
4749

@@ -74,8 +76,9 @@ contract ZapFacet is Modifiers, ReentrancyGuard {
7476
PermitSignature calldata _permitSignature,
7577
OnboardingApproval calldata _onboardingApproval
7678
) external notLocked nonReentrant {
77-
// Check if it's a supported ERC20 token
78-
require(LibAdmin._isSupportedExternalTokenAddress(_externalTokenAddress), "zapOrder: invalid ERC20 token");
79+
if (!LibAdmin._isSupportedExternalTokenAddress(_externalTokenAddress)) {
80+
revert InvalidERC20Token(_externalTokenAddress, "zapOrder");
81+
}
7982

8083
bytes32 parentId = _onboardingApproval.entityId;
8184

src/shared/CustomErrors.sol

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,8 @@ error InvalidTokenId();
201201

202202
/// @dev Cannot stake an amount lower than objectMinimumSell[tokenId].
203203
error InvalidStakingAmount();
204+
205+
/// @dev Not a supported external ERC 20 token
206+
/// @param tokenAddress Address of the ERC20 token
207+
/// @param method Name of the method that threw the error
208+
error InvalidERC20Token(address tokenAddress, string method);

test/T03TokenizedVault.t.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ contract T03TokenizedVaultTest is D03ProtocolDefaults, MockAccounts {
109109
vm.expectRevert("extDeposit: invalid receiver");
110110
nayms.externalDeposit(wethAddress, 1);
111111

112-
vm.expectRevert("extDeposit: invalid ERC20 token");
112+
vm.expectRevert(abi.encodeWithSelector(InvalidERC20Token.selector, address(0xBADAAAAAAAAA), "extDeposit"));
113113
nayms.externalDeposit(address(0xBADAAAAAAAAA), 1);
114114

115115
// deposit to entity1

test/T07Zaps.t.sol

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pragma solidity 0.8.20;
44
import { D03ProtocolDefaults, LC, LibHelpers, StdStyle } from "./defaults/D03ProtocolDefaults.sol";
55
import { DummyToken } from "test/utils/DummyToken.sol";
66
import { StakingConfig, PermitSignature, OnboardingApproval } from "src/shared/FreeStructs.sol";
7+
import { InvalidERC20Token } from "src/shared/CustomErrors.sol";
78

89
import { InvalidSignatureLength } from "src/shared/CustomErrors.sol";
910

@@ -76,7 +77,7 @@ contract ZapFacetTest is D03ProtocolDefaults {
7677
PermitSignature memory permitSignature = PermitSignature({ deadline: deadline, v: v, r: r, s: s });
7778
OnboardingApproval memory approval;
7879

79-
vm.expectRevert("zapStake: invalid ERC20 token");
80+
vm.expectRevert(abi.encodeWithSelector(InvalidERC20Token.selector, address(111), "zapStake"));
8081
nayms.zapStake(address(111), nlf.entityId, stakeAmount, stakeAmount, permitSignature, approval);
8182

8283
nayms.zapStake(address(naymToken), nlf.entityId, stakeAmount, stakeAmount, permitSignature, approval);
@@ -117,7 +118,7 @@ contract ZapFacetTest is D03ProtocolDefaults {
117118
OnboardingApproval memory onboardingApproval = OnboardingApproval({ entityId: sue.entityId, roleId: cpRoleId, signature: sig });
118119

119120
// verify token address
120-
vm.expectRevert("zapOrder: invalid ERC20 token");
121+
vm.expectRevert(abi.encodeWithSelector(InvalidERC20Token.selector, address(111), "zapOrder"));
121122
nayms.zapOrder(address(111), 10 ether, wethId, 1 ether, bob.entityId, 1 ether, permitSignature, onboardingApproval);
122123

123124
OnboardingApproval memory oa = OnboardingApproval ({

test/fixtures/TokenizedVaultFixture.sol

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ pragma solidity 0.8.20;
33

44
import { LibTokenizedVaultIO } from "src/libs/LibTokenizedVaultIO.sol";
55
import { LibAdmin } from "src/libs/LibAdmin.sol";
6+
import { InvalidERC20Token } from "src/shared/CustomErrors.sol";
67

78
contract TokenizedVaultFixture {
89
function externalDepositDirect(bytes32 _to, address _externalTokenAddress, uint256 _amount) public {
9-
// a user can only deposit an approved external ERC20 token
10-
require(LibAdmin._isSupportedExternalTokenAddress(_externalTokenAddress), "extDeposit: invalid ERC20 token");
10+
if (!LibAdmin._isSupportedExternalTokenAddress(_externalTokenAddress)) {
11+
revert InvalidERC20Token(_externalTokenAddress, "extDeposit");
12+
}
1113
LibTokenizedVaultIO._externalDeposit(_to, _externalTokenAddress, _amount);
1214
}
1315
}

0 commit comments

Comments
 (0)