DeFiFoundry
60,000 USDC
View results
Submission Details
Severity: low
Valid

Non-Compliance Issues with EIP7201

Summary

Multiple contracts fail to comply with the EIP7201 standard for computing slot locations. This non-compliance violates an invariant stated in the project's README.

Vulnerability Details

There are two separate types of non-compliance observed: the absence of EIP7201 application (Referral.sol) and incorrect application where the ID is wrongly computed (CustomReferralConfiguration.sol, etc.).

More details as follows:

  • Found in src/perpetuals/leaves/CustomReferralConfiguration.sol at Line 16

@>: eip7201 NAMESPACE_ID should be concat of fi.zaros.CustomReferralConfiguration + customReferralCode before applying the erc7201(id: string) formula

11: function load(string memory customReferralCode)
...
15: {
16:@> bytes32 slot = keccak256(abi.encode(CUSTOM_REFERRAL_CONFIGURATION_DOMAIN, customReferralCode));
17:
...
21: }
  • Found in src/perpetuals/leaves/MarginCollateralConfiguration.sol at Line 39

@>: eip7201 NAMESPACE_ID should be concat of fi.zaros.perpetuals.MarginCollateralConfiguration + collateralType before applying the erc7201(id: string) formula

38: function load(address collateralType) internal pure returns (Data storage marginCollateralConfiguration) {
39:@> bytes32 slot = keccak256(abi.encode(MARGIN_COLLATERAL_CONFIGURATION_LOCATION, collateralType));
40: assembly {
...
43: }
  • Found in src/perpetuals/leaves/MarketOrder.sol at Line 26

@>: eip7201 NAMESPACE_ID should be concat of fi.zaros.perpetuals.MarketOrder + tradingAccountId before applying the erc7201(id: string) formula

25: function load(uint128 tradingAccountId) internal pure returns (Data storage self) {
26:@> bytes32 slot = keccak256(abi.encode(MARKET_ORDER_LOCATION, tradingAccountId));
27:
...
31: }
  • Found in src/perpetuals/leaves/PerpMarket.sol at Line 64

@>: eip7201 NAMESPACE_ID should be concat of fi.zaros.perpetuals.PerpMarket + marketId before applying the erc7201(id: string) formula

63: function load(uint128 marketId) internal pure returns (Data storage perpMarket) {
64:@> bytes32 slot = keccak256(abi.encode(PERP_MARKET_LOCATION, marketId));
65: assembly {
...
68: }
  • Found in src/perpetuals/leaves/Position.sol at Line 45

@>: eip7201 NAMESPACE_ID should be string concat of fi.zaros.perpetuals.Position + tradingAccountId + marketId before applying the erc7201(id: string) formula

44: function load(uint128 tradingAccountId, uint128 marketId) internal pure returns (Data storage position) {
45:@> bytes32 slot = keccak256(abi.encode(POSITION_LOCATION, tradingAccountId, marketId));
46:
...
50: }
  • Found in src/perpetuals/leaves/Referral.sol at Line 16

@>: namespace id was computed but not applying EIP7201(namespaceId) formula.

15: function load(address accountOwner) internal pure returns (Data storage referralTestnet) {
16:@> bytes32 slot = keccak256(abi.encode(REFERRAL_DOMAIN, accountOwner));
17: assembly {
...
20: }
  • Found in src/perpetuals/leaves/SettlementConfiguration.sol at Line 70

@>: eip7201 NAMESPACE_ID should be string concat of fi.zaros.perpetuals.SettlementConfiguration + marketId + settlementConfigurationId before applying the erc7201(id: string) formula

62: function load(
...
69: {
70:@> bytes32 slot = keccak256(abi.encode(SETTLEMENT_CONFIGURATION_LOCATION, marketId, settlementConfigurationId));
71: assembly {
...
74: }
  • Found in src/perpetuals/leaves/TradingAccount.sol at Line 60

@>: eip7201 NAMESPACE_ID should be string concat of fi.zaros.perpetuals.TradingAccount + tradingAccountId before applying the erc7201(id: string) formula

59: function load(uint128 tradingAccountId) internal pure returns (Data storage tradingAccount) {
60:@> bytes32 slot = keccak256(abi.encode(TRADING_ACCOUNT_LOCATION, tradingAccountId));
61: assembly {
...
64: }

Impact

The severity of EIP Non-compliance and invariant breaking should be Medium.

Tools Used

Manual Review

Recommendations

After computing the namespace ID from the corresponding slot domain and related parameters, apply the EIP7201 formula on the ID to obtain a unique slot via:

bytes32 slot = keccak256(abi.encode(uint256(abi.encode(ID)) - 1)) & ~bytes32(uint256(0xff));
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Storage computation formula of ERC7201 is not followed. ERC7201 non compliance.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.