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

[TESTNET BUG] contract-of can't be used with traits from function parameters in clarity within a let context #1815

Closed
1 of 13 tasks
friedger opened this issue Aug 19, 2020 · 6 comments
Assignees
Labels
bug Unwanted or unintended property causing functional harm testnet

Comments

@friedger
Copy link
Collaborator

friedger commented Aug 19, 2020

Describe the bug

Given there is a function with a trait as a parameter and the function body contains a call to contract-of with this trait then this function can't be used.

When calling the function the parameter is a contract principal, but contract-of requires a trait type and the call fails with Unchecked(ContractOfExpectsTrait)

Steps To Reproduce

clarity contract

(define-public (contract-of-trait (tradables <tradables-trait>)
    (ok (contract-of tradables))
)

In unit test using a client:

  async callWithTrait(
    contractName: string,
    params: { sender: string }
  ): Promise<Receipt> {
    const tx = this.createTransaction({
      method: {
        name: "contract-of-trait",
        args: [`'${contractName}`],
      },
    });
    await tx.sign(params.sender);
    const receipt = await this.submitTransaction(tx);
    return receipt;
  }

Expected behavior

The contract call should return the contract principal

Environment

  • Output of stacks-node version
    stacks-node 0.1.0 => 23.0.0.0 (master:2fb1dcf+, release build, linux [x86_64])

Additional context

Discovered during development of https://github.com/friedger/clarity-marketplace

If you think this is eligible for a bug bounty, please check the relevant boxes below:

Critical, Launch Blocking Bugs

Consensus critical bugs

  • Can cause a chain split
  • Can cause an invalid transaction to get mined
  • Can cause an invalid block to get accepted
  • Can cause a node to stall

State corruption

  • Can modify a smart contract’s data maps and data vars without a `contract-call?

Stolen funds

  • Any address losing STX without a corresponding transfer
  • Modify token balances and NFT ownership in other contracts without a contract-call?

Take control and/or bring network to a halt

  • Take control and/or bring network to a halt

Major, Launch Blocking Bugs

Major bugs

  • Performance or correctness bugs that don’t rise to P0 level
  • Stress test or DoS attacks that slow things down enough
  • Resource exhaustion
  • Expected functionality doesn’t work in obvious ways (important to be super specific with this wording)

Minor, Non-launch blocking bugs

Minor bugs

  • Bugs in non-critical software (CLI, UI, etc) that doesn’t impact critical functionality

@timstackblock

@friedger friedger added bug Unwanted or unintended property causing functional harm testnet labels Aug 19, 2020
@psq
Copy link
Contributor

psq commented Aug 19, 2020

I can't rename the issue, but the description is not accurate (it was hard to tell). The problem comes from the additional scope added by let which makes the trait unresolvable.

If you modify your contract to:

(define-public (bid (tradables <tradables-trait>) (tradable-id uint) (price uint))
  (let ((contract (contract-of tradables)) (tradable-owner (unwrap-panic (get-owner tradables tradable-id))))
    (ok (map-insert offers {bid-owner: tx-sender, owner: tradable-owner, tradables: contract, tradable-id: tradable-id}
                {price: price}))
  )
)

all 4 tests will pass.

Maybe @lgalabru might have some ideas why context.callable_contracts.get(contract_ref) works outside the let scope, but no longer inside it even though it seems to create a new context with the right value.

For @lgalabru benefit, the original function was:

(define-public (bid (tradables <tradables-trait>) (tradable-id uint) (price uint))
  (let ((tradable-owner (unwrap-panic (get-owner tradables tradable-id))))
    (ok (map-insert offers {bid-owner: tx-sender, owner: tradable-owner, tradables: (contract-of tradables), tradable-id: tradable-id}
                {price: price}))
  )
)

@psq
Copy link
Contributor

psq commented Aug 19, 2020

possibly something not fully addressed by #1643?

@timstackblock
Copy link
Contributor

Thanks for the submission @friedger 👍

@lgalabru
Copy link
Member

Working on a fix - #1817

@friedger friedger changed the title [TESTNET BUG] contract-of can't be used with traits from function parameters in clarity [TESTNET BUG] contract-of can't be used with traits from function parameters in clarity within a let context Aug 21, 2020
@jcnelson
Copy link
Member

@friedger this should be merged to master. Can you confirm that it fixes your issue?

@friedger
Copy link
Collaborator Author

@jcnelson I ran the tests with the lastest clarity-cli from master successfully. Thank you.

Krypton: Stacks 2.0 Testnet Phase 3 automation moved this from New Issues to Done Aug 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Unwanted or unintended property causing functional harm testnet
Projects
No open projects
Development

No branches or pull requests

5 participants