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

Wrong constant value in the signers.clar boot contract #370

Open
hugocaillard opened this issue Mar 21, 2024 · 3 comments
Open

Wrong constant value in the signers.clar boot contract #370

hugocaillard opened this issue Mar 21, 2024 · 3 comments
Assignees
Labels
bug Something isn't working
Milestone

Comments

@hugocaillard
Copy link
Collaborator

The signers.clar boot contracts has this function

(define-constant CHUNK_SIZE (* u2 u1024 u1024))

;; ...

(define-read-only (stackerdb-get-config)
	(ok
		{ chunk-size: CHUNK_SIZE,
		  write-freq: u0,
		  max-writes: MAX_WRITES,
		  max-neighbors: u32,
		  hint-replicas: (list ) }
	))

When calling this method with clarinet console with --enable-clarity-wasm, it returns a chunk-size of 0.

I tried it with my local build of clarinet that has the latest clar2wasm version (from the main branch).

(contract-call? 'ST000000000000000000002AMW42H.signers stackerdb-get-config)
@Acaccia Acaccia added the bug Something isn't working label Mar 21, 2024
@hugocaillard
Copy link
Collaborator Author

I think that it's same issue but with another use case, in the pox-4 contract we use an expression to define the STACKING_THRESHOLD constant, it evaluates to 0 in WASM

(define-constant STACKING_THRESHOLD_25 (if is-in-mainnet u20000 u8000))

(define-read-only (get-st25)
  STACKING_THRESHOLD_25
)

In because the contract also does

(define-read-only (get-stacking-minimum)
    (/ stx-liquid-supply STACKING_THRESHOLD_25))

it leads to a division by zero when we call get-stacking-minimum or get-pox-info (which the new boot contract signers-voting.clar does, so it can't be deployed in clar2wasm)

@Acaccia
Copy link
Collaborator

Acaccia commented Mar 21, 2024

So, after a little bit of investigation, the bug is caused by the fact that a constant which is not a literal value is not evaluated if it's called from inside a function. This is because in this case, .top-level is not evaluated.

We have to make sure that an accessed constant has been evaluated first.

Here is a simple way to reproduce the bug in the clar2wasm-tests package:

  1. Add the contract constant-expr.clar with this content:
(define-constant FOO (+ 1 1))

(define-public (get-constant)
	(ok FOO)
)
  1. Add in lib_tests.rs this test:
test_contract_call_response!(
    test_contract_constant_expr,
    "constant-expr",
    "get-constant",
    |response: ResponseData| {
        assert!(response.committed);
        assert_eq!(*response.data, Value::some(Value::Int(2)).unwrap());
    }
);

@Acaccia
Copy link
Collaborator

Acaccia commented Mar 21, 2024

Our traverse function for define-constant should also handle other cases than literal values at compile time, like atoms for reserved variables (e.g. tx-sender).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: Status: 📋 Backlog
Development

No branches or pull requests

3 participants