Curriculum·G304 Testing and the Toolchain·about 34 min

The migration and deployment checklist

By the end of this lesson you can

  • →Explain that migrations and deployments are high-risk moments that need a disciplined checklist
  • →Describe how an inconsistent constant introduced in Uranium Finance's v2 migration let an attacker drain about 57 million dollars
  • →Reason that a change made during a migration is invisible to the old tests and can be catastrophic live
  • →Adopt a migration checklist: diff every changed value, re-verify invariants, and test the migrated state

Graduate · enrolled learners

This lesson opens with Uranium Finance, April 2021.

What happened
Uranium Finance ran an exchange on BNB Chain and migrated to a second version of its contracts. Its trading pairs enforced a balance invariant using a numeric constant, and during the migration that constant was changed inconsistently: the constant was changed from 1000 to 10000 in two places in the calculation but left at 1000 at the end, a factor-of-ten mismatch. With the invariant check now wrong, an attacker could swap almost the entire reserves of a pair out of it while putting almost nothing in, because the broken check no longer enforced that value in must roughly match value out, and they drained about 57 million dollars. The individual contracts were not novel and the math was not exotic; the flaw was introduced by the migration itself, a single constant changed in two places and not a third, and because the change lived in the new deployment it was invisible to any test written against the old version. A disciplined migration review, diffing every changed constant and re-checking that the invariants still held in the migrated code, would have caught a factor-of-ten mismatch immediately, and the mismatch shipped about ten days after the v2 migration.
The decision point
Migrations and deployments are the highest-risk moments in a contract's life, because they change the code that holds value and do so in ways the existing tests, written against the old version, cannot see, so a single inconsistent value introduced during a migration can be both invisible to the old tests and catastrophic once live. Uranium Finance is the case: a numeric constant in a pair's balance invariant was changed from 1000 to 10000 in two places while the final factor stayed at 1000, a factor-of-ten mismatch that broke the check enforcing value-in-matches-value-out, and an attacker swapped almost the entire reserves out for almost nothing, draining about 57 million dollars, all from one constant changed in two places and not a third. This is the deployment lesson that closes the course: the danger is not only in writing new code but in changing existing code, because a migration disturbs the assumptions the old tests encoded and can introduce a flaw that no old test covers and no casual glance catches. So the discipline is a migration and deployment checklist run every time: diff every value that changed and confirm each change is intended and consistent, re-verify that the contract's invariants still hold in the migrated code rather than assuming they carry over, and test the migrated state directly rather than trusting the tests of the version you left behind. Uranium Finance is what a migration without that discipline produces: a factor-of-ten typo in a constant, invisible to the old tests and worth 57 million dollars to whoever noticed it, which is exactly the kind of change a checklist exists to catch and a deploy in a hurry ships.
Recorded loss
$57,000,000

What you will be able to answer

  • →How was Uranium Finance drained (April 2021)?
  • →Why are migrations and deployments especially high-risk?
  • →Why was Uranium's broken constant invisible to its tests?
  • →What does a migration and deployment checklist require?

Orientation and Year One are open: anyone can read them without an account. From Year Two onward the lessons are for enrolled learners, because progress through the later years only means anything if it is tracked against a record.

It is free. We do not sell the list and there is nothing to buy at the end of it.

Sources and review

Confidence high·Volatility low·Reviewed 2026-09-17·Owner unassigned

Contested

Rekt puts the April 2021 Uranium Finance loss at no less than 57 million dollars, approximately 57.2 million at the time of writing; the dollar value depends on the prices of the drained assets, so reported figures vary somewhat. The lesson uses the migration-introduced-constant mechanism, not a precise final loss.

Rekt says the constant was changed from 1,000 to 10,000 in two places but not at the end, that the old version did not have the bug, that the v2 migration came about ten days before the exploit on 28 April 2021, and that the broken check let 1 wei in buy 98 percent of the output token. That the change was invisible to tests written against the old version, and that a migration diff would have caught it, is this lesson's reading; Rekt does not say what testing or review was done. The lesson summarizes the flaw as a factor-of-ten mismatch in a balance check introduced during the migration, which is the transferable point rather than the full code.