- `TokenUri` exists to hold the token metadata, and `SantasList` inherits it so `tokenURI()` can
return the blob. The specification calls it *"a separate contract inherited by `SantasList` for
readability purposes."*
- A `string public constant` is inlined verbatim into the runtime bytecode of every contract that
inherits it. The constant is 51,613 bytes, which puts `SantasList` at **61,030 bytes against the
24,576-byte EIP-170 cap** and its initcode at **70,811 against EIP-3860's 49,152**. The `CREATE`
returns oversized code and the deployment transaction reverts. Arbitrum One enforces EIP-170.
```solidity
// src/TokenUri.sol:9-11
contract TokenUri {
@> string public constant TOKEN_URI =
"data:application/json;base64,ewogICAgIm5hbWUiOiAi..."; // 51,613 bytes
// src/SantasList.sol:59
@> contract SantasList is ERC721, TokenUri { // inlines all 51,613 bytes
```
### Risk
**Likelihood:** High — this is a property of the audited commit, not a probability.
- `forge build --sizes` exits non-zero at the audited commit.
- Foundry raises the code-size limit for test deployments, so the shipped test suite passes against a
contract that cannot exist on-chain, and the repository's CI workflow is `on: workflow_dispatch`
only, so it never runs on push or pull request.
**Impact:**
- The protocol has no on-chain existence. Runtime overshoot is 36,454 bytes; `TokenUri` alone is
51,714 bytes and is over both caps by itself.
- No funds are at risk, because no funds can ever be deposited — which is why the impact is rated
Medium rather than High despite the disruption being total.
**This does not undercut the other findings.** `test/Claude/F06_IndependenceCheck.t.sol` deploys a
SantasList carrying **only** this mitigation at 8,998 bytes and demonstrates H-1, H-2, H-3, H-4,
HM-1 and M-1 all still working on it. Seven defects, seven disjoint fixes.
### Proof of Concept
```solidity
function test_F06_deployFailsUnderRealEip170() public {
// deployCode loads the artifact at runtime; `new SantasList()` would inline the
// 70,811-byte creation code into the TEST contract and make the suite undeployable.
try this.deploy() returns (address deployed) {
fail();
} catch {
// CREATE reverted: EvmError CreateContractSizeLimit
}
}
function deploy() external returns (address) { return deployCode("SantasList.sol:SantasList"); }
```
### Recommended Mitigation
```diff
- contract SantasList is ERC721, TokenUri {
+ contract SantasList is ERC721 {
function tokenURI(uint256) public pure override returns (string memory) {
- return TOKEN_URI;
+ return "ipfs://<metadata-cid>";
}
```
Alternatively keep `TokenUri` as a separately deployed contract that `SantasList` calls — note it is
over both caps on its own, so it must also be split or moved off-chain — or store the blob with
SSTORE2 and read it at runtime. Add `forge build --sizes` to CI, which currently triggers only on `workflow_dispatch`.
## Description Oversized contract will make deployment fail ## Vulnerability Details `SantasList.sol:SantasList` contract is oversized (56.43 kB). This is due to the fact that the constant variable `TOKEN_URI` is stored in the bytecode, which is `51373` characters in length. Oversized contract can't be deployed. ### PoC ``` forge build --sizes [⠒] Compiling... [⠊] Compiling 2 files with 0.8.22 [⠒] Solc 0.8.22 finished in 1.85s Compiler run successful! | Contract | Size (kB) | Margin (kB) | |----------------|-----------|-------------| | Math | 0.086 | 24.49 | | MockERC20 | 3.69 | 20.886 | | MockERC721 | 3.827 | 20.749 | | SantaToken | 3.324 | 21.252 | | SantasList | 56.43 | -31.854 | | SignedMath | 0.086 | 24.49 | | StdStyle | 0.086 | 24.49 | | Strings | 0.086 | 24.49 | | TokenUri | 51.615 | -27.039 | | console | 0.086 | 24.49 | | console2 | 0.086 | 24.49 | | safeconsole | 0.086 | 24.49 | | stdError | 0.592 | 23.984 | | stdJson | 0.086 | 24.49 | | stdMath | 0.086 | 24.49 | | stdStorage | 0.086 | 24.49 | | stdStorageSafe | 0.086 | 24.49 | ``` ## Impact MEDIUM. Contract can't be deployed due to the `TOKEN_URI` size. ## Recommendations `TOKEN_URI` should be modified to prevent the oversized contract. Ideally, this can be an `ipfs` url, which will be shorter.
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.