---
# System prepended metadata

title: Veridise

---

# Veridise

## Formalization

1. A RefundableCrowdsale’s `claimRefund` transaction will revert if `goalReached()` or not `isFinalized`

reverted(claimRefund, goalReached() || !isFinalized)

2. After a RefundableCrowdsale `withdraw` transaction, `msg.sender`’s balance should increase by the original value (before the execution of the `withdraw` transaction) of `balanceOf(msg.sender)` and `balanceOf(msg.sender)` should be `0`.

Let `b` be `msg.sender`’s balance.

finished(withdraw, b = old(b) + old(balanceOf(msg.sender)) && balanceOf(msg.sender) = 0)

## Verification

I'm a bit confused by this question - am I to check if these two statements hold, or that if pre does entail post after `attempt`?

If it's the latter then it does entail, because every state with `started && msg.value > cost` does go through the function correctly and its effect is exactly the postcondition.

And if it's the former:

1. Precondition: `started(Game.attempt(guess), started && msg.value > cost)`

This does not always hold. `attempt(guess)` can be called with `msg.value <= cost` where `require(msg.value > cost)` will fail. And, after any time `attempt(guess)` is called with `result == target` and before any `setTarget(t)` is called, `attempt(guess)` can be called with `!started` in which case `require(started)` will fail.

2. Postcondition: `finished(Game.attempt(guess), value = fsum(Game.attempt(guess), guess))`

This always holds. Every time `Game.attempt(guess)` succeeds, `value` equals to the sum of all the `guess`s from all the time it is run.

## Detection

1. Anyone can call `setTarget`.
2. When `value` is too big, it could be that all the correct `guess`s would overflow `value`.
3. Reentrancy attack is possible where attacker guesses right and then drains the fund before `started` is set to `false`.

## Exploit

I think an exploit is possible because the contract does not check what the input `data` contains before executing it. I'm not sure what exactly can it do, but considering arbitrary code is possible, I assume there is an exploit.

## Tooling

I couldn't set up Typescript and Solidity correctly so I ran the `sol-ast-compile --tree` directly on the example program. I reasoned that, the detection script should, during the traversal of the AST, upon meeting a node of type `FunctionCall`, check if it is an "external" call where there should be a pre-determined list of such calls including `msg.sender.call`, and, if it is, mark the current `Block` and continue the traversal until its end or when an `Assignment` is met, in which case it decides that reentrancy is possible.