Skip to content

Latest commit

 

History

History
33 lines (24 loc) · 2.11 KB

File metadata and controls

33 lines (24 loc) · 2.11 KB

L1 to L2 Address Conversion

In Starknet, addresses are of the felt type, while on L1 addresses are of the uint160 type. To pass address types during cross-layer messaging, the address variable is typically given as a uint256. However, this may create an issue where an address on L1 maps to the zero address (or an unexpected address) on L2. This is because the primitive type in Cairo is the felt, which lies within the range 0 < x < P, where P is the prime order of the curve. Usually, we have P = 2^251 + 17 * 2^192 + 1.

Example

Consider the following code to initiate L2 deposits from L1. The first example has no checks on the to parameter, and depending on the user's address, it could transfer tokens to an unexpected address on L2. The second example, however, adds verification to ensure this does not happen. Note that the code is a simplified version of how messages are sent on L1 and processed on L2. For a more comprehensive overview, see here: https://www.cairo-lang.org/docs/hello_starknet/l1l2.html.

contract L1ToL2Bridge {
    uint256 public constant STARKNET_FIELD_PRIME; // the prime order P of the elliptic curve used
    IERC20 public constant token; // some token to deposit on L2

    event Deposited(uint256 to, uint256 amount);

    function badDepositToL2(uint256 to, uint256 amount) public returns (bool) {
        token.transferFrom(msg.sender, address(this), amount);
        emit Deposited(to, amount); // this message gets processed on L2
        return true;
    }

    function betterDepositToL2(uint256 to, uint256 amount) public returns (bool) {
        require(to != 0 && to < STARKNET_FIELD_PRIME, "invalid address"); // verifies 0 < to < P
        token.transferFrom(msg.sender, address(this), amount);
        emit Deposited(to, amount); // this message gets processed on L2
        return true;
    }
}

Mitigations

When sending a message from L1 to L2, ensure verification of parameters, particularly user-supplied ones. Keep in mind that Cairo's default felt type range is smaller than the uint256 type used by Solidity.