Skip to content

Commit

Permalink
✨ Add axelar-proxy-contract-id detector
Browse files Browse the repository at this point in the history
  • Loading branch information
michprev committed Mar 13, 2024
1 parent 36523a5 commit 801ef8e
Show file tree
Hide file tree
Showing 4 changed files with 456 additions and 0 deletions.
91 changes: 91 additions & 0 deletions docs/static-analysis/detectors/axelar-proxy-contract-id.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Axelar proxy `contractId` detector

The detector detects Axelar proxy and implementation contracts that use the `contractId` method as an additional check for deploying the contracts and when performing an upgrade.

## Proxy `contractId` shared between multiple contracts

Two different proxy contracts should not share the same `contractId`.

```solidity hl_lines="13 25" linenums="1"
pragma solidity ^0.8.0;
import { Proxy } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Proxy.sol';
contract MyProxy is Proxy {
constructor(
address implementationAddress,
address owner,
bytes memory setupParams
) Proxy(implementationAddress, owner, setupParams) {}
function contractId() internal pure virtual override returns (bytes32) {
return keccak256('my-proxy');
}
}
contract AnotherProxy is Proxy {
constructor(
address implementationAddress,
address owner,
bytes memory setupParams
) Proxy(implementationAddress, owner, setupParams) {}
function contractId() internal pure virtual override returns (bytes32) {
return keccak256('my-proxy');
}
}
```

## Proxy contract without upgradeable contract with the same `contractId`

It is expected that a project will have at least one implementation contract with the same `contractId` as the proxy contract.
Proxy contracts without an implementation contract with the same `contractId` are reported.

## Implementation contract without proxy contract with the same `contractId`

It is expected that a project will have exactly one proxy contract with the same `contractId` as the implementation contract.
Implementation contracts without a proxy contract with the same `contractId` are reported.

## Proxy contract and upgradeable contract with function selector collision

An implementation contract and a corresponding proxy contract should not define functions with the same function selector.
It wouldn't be possible to call the implementation contract function in this case, as the proxy contract function would be called instead.

The `:::solidity implementation()` and `:::solidity setup(bytes calldata params)` functions are an exception to this rule and are not reported.

```solidity hl_lines="9-11 21-23" linenums="1"
pragma solidity ^0.8.0;
import { Proxy } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Proxy.sol';
import { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol';
contract MyProxy is Proxy {
constructor(address implementationAddress, address owner, bytes memory setupParams) Proxy(implementationAddress, owner, setupParams) {}
function kind() external pure returns (string memory) {
return 'proxy';
}
function contractId() internal pure virtual override returns (bytes32) {
return keccak256('test');
}
}
contract MyImplementation is Upgradable {
constructor() Upgradable() {}
function kind() external pure returns (string memory) { // (1)!
return 'implementation';
}
function contractId() external pure returns (bytes32) {
return keccak256('test');
}
}
```

1. It will never be possible to call the `kind` function of the implementation contract, as the proxy contract function will be called instead.

## Parameters

The detector does not accept any additional parameters.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ nav:
- Built-in:
- Detectors:
- abi.encodeWithSignature: 'static-analysis/detectors/abi-encode-with-signature.md'
- Axelar proxy contractId: 'static-analysis/detectors/axelar-proxy-contract-id.md'
- Balance relied on: 'static-analysis/detectors/balance-relied-on.md'
- Calldata tuple reencoding head overflow bug: 'static-analysis/detectors/calldata-tuple-reencoding-head-overflow-bug.md'
- Call options not called: 'static-analysis/detectors/call-options-not-called.md'
Expand Down
1 change: 1 addition & 0 deletions wake_detectors/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .abi_encode_with_signature import AbiEncodeWithSignatureDetector
from .axelar_proxy_contract_id import AxelarProxyContractIdDetector
from .balance_relied_on import BalanceReliedOnDetector
from .call_options_not_called import CallOptionsNotCalledDetector
from .calldata_tuple_reencoding_head_overflow_bug import (
Expand Down
Loading

0 comments on commit 801ef8e

Please sign in to comment.