MTT-Induced Vulnerabilities in Randomized Events

This VIP underscores the ease with which MTT can be exploited, even by those with minimal coding expertise, using available community-developed tools. Such exploitation poses a significant threat as it allows users to manipulate outcomes in various blockchain-based activities like games, NFT mints, and other applications that rely on randomization.



Raising with the technical team for further investigation.


I’m interested to know what the technical team thinks of this! It’s quite important for the community and builders to have a solution for this.

1 Like

would be great to expand more on your idea’s for the use of oracles!


Is this similar to to the VIP regarding Private State Variable Visibility Exposure? The same issue but from a different perspective?

I think provides a useful scenario exposing this vulnerability and also a design on how to avoid being impacted by this vulnerability from a dApp developer perspective. Multi-Task atomic Transactions –

I would say they are vaguely in the same field, but not similar. The private state variable is only inclusive of a private and internal variables changed within a transaction that can be exploited with a contract, which is expected to be private/internal from other EVM chains. This involves any variable change in any unintended way without the use of a custom contract and can be exploited with currently available no-code tools.

Yes, wrote up a blog for this vulnerability after I discussed it with him to provide immediate access for developers to help avoid these common pitfalls, but over a year later and without a foundation-sponsored VIP recommendation, all current randomized minting platforms are still vulnerable. I have also had to notify and display the exploit to platforms performing randomized events twice within the last 3 months.

1 Like

@databeforedishonor appreciate the actions that you have taken to notify and ensure that developers are aware of this issue with regards to randomized events.

As has described there is an approach to ensure the safe use of randomized events in combination with clauses. However, your preference would be that the protocol resolve this issue rather than a developer.

I hope some of the devs will jump into the discussion in the coming days and we can identify whether there is anything that can be done on the protocol level to reduce or prevent this sort of vulnerability.

At a minimum we should at least have some documentation to capture the approach a developer should take, similar to the documentation, when working with randomized events on the VechainThor blockchain to inform developers.


Sounds good.

My initial assumption, if possible at least, for a fix to this at the protocol level would be adopting a built-in extension that can limit the number of clauses contained within a transaction in a similar way that you can capture other builtin extension functions. Another way to capture is capture the number of clauses within a tx and each clause a clauseIndex. If the clauses are counted prior to bundling the clause, a developer could compare the clause count to the clauseIndex

This would at least allow randomized events to use this modifier/built-in to retain similar security as other EVMs without worrying about the MTT aspect

1 Like

Example with explanation of possible protocol solution.

Coin flip contract. Heads you win 10 ERC20 tokens, tails you lose.

I flip with an empty wallet.

Attempt 1:
Clause 1: flip coin. Result: Tails
Clause 2: transfer 10 tokens to wallet B (reverts whole tx due to balanceOf(token)= 0)

Attempt 2:
Clause 1: flip result: heads
Clause 2: transfer 10 tokens to wallet B (success. balanceOf(token)=10)

Possible solution:

Add 2 builtin view functions available for developers.

totalClauses()- Knows the count of clauses at beginning of tx

clauseIndex()- when clauses are iterated into a tx, clauseIndex is available to view

Using these 2 functions, a developer can opt-in to make modifiers preventing clauses from coming after these events

onlyLastClause(ext.totalClauses()== ext.clauseIndex())

1 Like