Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provable.if in runtimeMethod does not work #26

Open
dloghin opened this issue Sep 25, 2024 · 1 comment
Open

Provable.if in runtimeMethod does not work #26

dloghin opened this issue Sep 25, 2024 · 1 comment

Comments

@dloghin
Copy link

dloghin commented Sep 25, 2024

We discovered this issue during the ETHGlobal Singapore Hackathon.

Suppose we want to update a balance based on a certain amount, such that if amount > balance we top up the balance (balance += amount - balance), else we withdraw (balance -= balance - amount). We do this with provable if:

    const condition = amount.greaterThan(currBalance);
    const diff = Provable.if(
      condition,
      Balance,
      amount.sub(currBalance),
      currBalance.sub(amount)
    );
    const to = Provable.if(
      condition,
      PublicKey,
      address,
      addressPool
    );
    const from = Provable.if(
      condition,
      PublicKey,
      addressPool,
      address
    );
    const d = UInt64.Unsafe.fromField(diff.value);
    await this.transfer(tokenId, from, to, d);

(see balances.ts in my fork)

The test fails either when amount > balance or amount < balance. It only passes when amount == balance (see the test at line 50 of balances.test.ts in my fork).

starter-kit commit: ed6ced5
node version: v18.20.4
pnpm version: 9.8.0

@dloghin dloghin changed the title Provable.if in runtimeMethod doe snot work Provable.if in runtimeMethod does not work Sep 25, 2024
@rpanic
Copy link
Member

rpanic commented Sep 25, 2024

@dloghin In o1js and protokit, all of your code will always be executed, this means both branches of all Provable.if calls will be called, but only one will be returned. And the UInt64 is built in a way that protects you from underflows, for example 2 - 5 = -3 -> we can't have minus values since it's a uint.
However, you built your code in a way that one of your branches will always underflow (in the if that computes diff), no matter the inputs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants