Ampleforth

QuantstampFiles named in the report

Quantstamp reviewed AMPL (Ampleforth) on 13 Jun 2019: 8 findings, 0 critical; 6 marked fixed, 2 open.

No open critical findings
Open the reportOpen AMPL’s security record

Report hosted on certificate.quantstamp.com.

Trustblock does not review code.

Findings8

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical000
High000
Medium000
Low206
LowAllowance Double-Spend ExploitFixed

As it presently is constructed, the contract is vulnerable to the allowance double-spend exploit, as with other ERC20 tokens. Exploit Scenario: 1. Alice allows Bob to transfer N amount of Alice's tokens (N>0) by calling the approve() method on smart contract (passing Bob's address and N as method arguments) 2. After some time, Alice decides to change from N to M (M>0) the number of Alice's tokens Bob is allowed to transfer, so she calls the approve()method again, this time passing Bob's address and M as method arguments 3. Bob notices Alice's second transaction before it was mined and quickly sends another transaction that calls the transferFrom() method to transfer N Alice's tokens somewhere 4. If Bob's transaction will be executed before Alice's transaction, then Bob will successfully transfer N Alice's tokens and will gain an ability to transfer another M tokens 5. Before Alice notices any irregularities, Bob calls transferFrom() method again, this time to transfer M Alice's tokens.

LowCentralization of PowerFixed

Smart contracts will often have owner variables to designate the person with special privileges to make modifications to the smart contract. The owner of UFragments may (un)pause rebasing and transfers. The owner of UFragmentsPolicy may set oracles and policy parameters. The owner of MedianOracle may arbitrarily whitelist data providers.

LowGas Usage / for Loop ConcernsFixed

Gas usage is a main concern for smart contract developers and users, since high gas costs may prevent users from wanting to use the smart contract. Even worse, some gas usage issues may prevent the contract from providing services entirely. For example, if a for loop requires too much gas to finish, then it may prevent the contract from functioning correctly entirely. Specifically, the gas usage in for loops depends on the number of providers and reports.

LowMalicious providers may perform DoS by making Select.computeMedian() revertFixed

getData() (used by rebase()) uses the function computeMedian() to compuute median of reported values from providers. In case of an even number of providers, it adds two middle values from the array. Malicious providers could collude and provide values that cause an overflow and, consequently, revert rebase().

LowRace Conditions / Front-RunningFixed

A block is an ordered collection of transactions from all around the network. It's possible for the ordering of these transactions to manipulate the end result of a block. A miner can take advantage of this by generating and moving transactions in a way that benefits themselves. In UFragmentsPolicy, there is a transaction ordering dependency between the functions setDeviationThreshold() (which sets the deviation threshold) and rebase() (which adjusts the token supply). In UFragments, there is a transaction ordering dependency between the functions transfer() (which sets the deviation threshold) and rebase() (which adjusts). A miner could take advantage of the ordering of transactions to sell their tokens at a higher rate than others. Exploit Scenario: 1. User calls UFragmentsPolicy.rebase() to adjust the supply and, indirectly, _gonsPerFragment so that its value increases. 2. Miner notices the transaction and realizes that due to increased _gonsPerFragment, they'll have less tokens. 3. The miner submits transfer() (e.g., as a part of an atomic swap with another token) to sell tokens, and orders it so that it gets executed before rebase().

LowToken may fail to converge to the target rate if rebase() keeps failingFixed

The function getData() iterates over all reports from the providers and counts the number of valid reports (i.e., not too old and not too recent). rebase() uses the return value from getData() and reverts if there are no valid reports. In case of a revert, no information is logged by getData() and the token fails to apply the previously computed dampening factor. If rebase() keeps failing over the course of rebaseLag (days), then the price will never reach the previously computed target rate.

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (12)

  • SelectMock.sol
  • Mock.sol
  • MockOracle.sol
  • Select.sol
  • MedianOracle.sol
  • UInt256LibMock.sol
  • UInt256Lib.sol
  • SafeMathInt.sol
  • SafeMathIntMock.sol
  • UFragments.sol
  • MockUFragments.sol
  • UFragmentsPolicy.sol

Part of AMPL’s security record

AMPL
Audits4 audits by 2 firmsLast audit Feb 2021, by CertiK.
Critical findingsNo open critical findingsAcross 4 reports.
Open AMPL’s security record

Security firm

Quantstamp

236 projects reviewed · 332 reports · latest Oct 2026

See Quantstamp’s audits

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us