Skip to content
  • Pinto Pasquale's avatar
    [#20] Update ManagedLedger implementation · d707cb99
    Pinto Pasquale authored and Fedor Sheremetyev's avatar Fedor Sheremetyev committed
    Problem: a couple of things can be improved in `ManagedLedger`'s implementation:
    1. in `transfer` the case where `from == to` is considered a no-op. There is no good motivation for this and perhaps even contradicts the `FA1.2`. Moreover, it increases the cost of the most common case (`from ≠ to`).
    2. approvals are stored as a `map` in the `ledger` `big_map`, which can be arbitrarily large. Only the owner of an address can make its `ledger` entry large (by calling `approve` many times).
       It's not a big problem in `ManagedLedger` (normally there is no incentive to break your own account), but it may break/spoil additional functionality in `ManagedLedger`-based contracts and it's just inefficient.
       Fortunately, since Carthagenet we can use `pair`s as keys in `big_map`s, so we can store approvals in a `big_map (pair address address) nat`.
    3. `approve` prohibits a non-zero to non-zero allowance change, to prevent its attack vector, however this is not fully secure (for example when two transactions change an allowance to `0` and then to a different value end up in the same block), nor is convenient.
       We can add an `allowanceCAS` entrypoint that additionally takes the expected current allowance as a parameter and fails if it does not match the actual current value, but otherwise permits non-zero to non-zero changes.
    Solution: we apply the necessary changes for each point:
    1. treat `from == to` as any other case in `transfer`.
    2. remove the approvals' `map` from the `ledger`'s entry and add another `big_map` to store them.
    3. add the new `approveCAS` entrypoint.