Skip to content

About Call Proxies

Miao ZhiCheng edited this page Jun 15, 2022 · 9 revisions

Stamped Ctx

Provide a transactional, secure and efficient heap-like shared memory data in EVM

TODO

Related: EIP-1153: Transient storage opcodes

Duck-type Polymorphic Calling Convention

  • No polymorphic approach: always add new entry functions for new agreement in host contract.
    • Pros: avoid duck tapes (hence type-safe)
    • Cons: more boiler plate.
  • callAgreement: duck tape "polymorphic" solution.
    • Pros: extremely flexible.
    • Cons: type-unsafe, may have security implications when handling calldata.
  • Better approach, e.g. "spec-haskell" type class, define AgreementOperation instances.
    • Pros: CORRECT WAY OF DOING THINGS.
    • Cons: not supported by dumb languages.

Scribbling Notes on Placeholder Ctx

Context (and its serialized version ctx) is a technique used in Superfluid framework to pass validatable serialized context structure between external calls within the same context.

The purpose of Context is to enable composable agreements. E.g. you send a stream, which starts another stream, the states need to be shared between the two agreement calls. This shared state may entail: the number of nested calls (for SuperApp callbacks), borrowed deposit, the original msg.sender, etc. (refer to ISuperfluid.sol and the Context struct for the full list of properties). Context can be thought of as trusted data which can only be altered by the Superfluid host, if the data can be altered at will, then it is not secure. It is important to note that this state is tracked within one transaction, at the end of the transaction, the Context is cleared.

In order to be able to pass ctx to the agreement function, such as:

function createFlow(
        ISuperfluidToken token,
        address receiver,
        int96 flowRate,
        bytes calldata ctx
    )

from top-level call:

    function callAgreement(
        ISuperAgreement agreementClass,
        bytes memory callData,
        bytes memory userData
    )

_replacePlaceholderCtx was used, this requires that the user provided abi encoded function call ends with a "0x" zero bytes data, a.k.a "placeholder" ctx, then the superfluid framework will reflate it with the actual stamped ctx, so that no one else can fake the ctx.

How the process looks like:

DATA PACKING:

0  : subscriber (32B)
32 : token (32B)
64 : indexId (32B)
96 : &placeHodlerCtx :: data (32B)
128: *placeHodlerCtx: [0, 0x] (32B) <--- to be replaced _replacePlaceholderCtx

=> _replacePlaceholderCtx replaces the actual *placeHodlerCtx 0x with ctx

STEP 1.b => reduce the length of data by 32B

0  : subscriber (32B)
32 : token (32B)
64 : indexId (32B)
96 : &placeHodlerCtx :: data (32B)

STEP 1.c => append actualCtx

0  : subscriber (32B)
32 : token (32B)
64 : indexId (32B)
96 : &actualCtx :: data (32B)
128: actualCtx: [CTX_LENGTH, CTX_RAW_DATA]
Clone this wiki locally