Sandboxed Oracle Environment
Only required for testing the dispute flow
Whenever the assertion is disputed on a production network this triggers DVM request to be resolved by UMA voters. This might be impractical to fully simulate this in a testing environment, hence, developers can use mocked oracle contract to resolve requests as they had been returned by DVM.
Interacting with Optimistic Oracle requires having whitelisted price identifier and bonding currency. In production networks these are approved by UMA token holders as part of governance voting. When testing, it might be easier for developers to use their own set of UMA ecosystem contracts where they have full control over such whitelisting process. Follow the written tutorial below or check out the video tutorial on Youtube.
Deploying sandboxed Oracle environment
A set of sandboxed UMA ecosystem contracts can be deployed using forge script from Optimistic Oracle V3 developers quick-start repository.
After cloning the repository make sure you have the latest Foundry version by running foundryup
command (see more installation details on Foundry book). From the root of the repository install dependencies with:
All script parameters are controlled through environment variables that should be exported before running the script:
ETH_RPC_URL
: URL of the RPC node to use for broadcasting deployment transactions on the desired test network.MNEMONIC
: Mnemonic of the account to use for deployment (derived account with 0 index will be used by default).ETHERSCAN_API_KEY
: API key for Etherscan, used for verifying deployed contracts.DEFAULT_IDENTIFIER
: Default identifier used by Optimistic Oracle V3 when resolving disputes. If not provided, this defaults toASSERT_TRUTH
identifier. The script will also whitelist this identifier.DEFAULT_LIVENESS
: Default liveness in seconds used by Optimistic Oracle V3 when settling assertions. If not provided, this defaults to7200
seconds.DEFAULT_CURRENCY
: Default currency used by Optimistic Oracle V3 when bonding assertions and disputes. The script will also whitelist this currency. If not provided, the script would also deploy a mintable ERC20 token and use it as the default currency based on following parameters:DEFAULT_CURRENCY_NAME
: Name of the new token. If not provided, this defaults toDefault Bond Token
.DEFAULT_CURRENCY_SYMBOL
: Symbol of the new token. If not provided, this defaults toDBT
.DEFAULT_CURRENCY_DECIMALS
: Number of decimals of the new token. If not provided, this defaults to18
.
MINIMUM_BOND
: Minimum bond amount in Wei of default currency required by Optimistic Oracle V3 when accepting new assertions. If not provided, this defaults to100e18
Wei.
Once all required environment variables are setup, deploy and verify the set of sandboxed UMA ecosystem contracts with:
At the top of the script output the addresses of the deployed contracts should be logged:
Finder
: Used to locate other UMA ecosystem contract addresses. Deployment script will have added newStore
,AddressWhitelist
,IdentifierWhitelist
,MockOracleAncillary
andOptimisticOracleV3
implementations.Store
: Stores final fees of bonding currencies. The script will have set the final fee of default currency to half of provided minimum bond amount since Optimistic Oracle V3 calculates minimum bond twice the value of this final fee.AddressWhitelist
: Stores approved currency addresses that can be used for bonding assertions and disputes. The script will have already whitelisted the default currency.IdentifierWhitelist
: Stores approved identifiers that can be used to resolve disputes at DVM. The script will have already whitelisted the default identifier.MockOracleAncillary
: Optimistic Oracle will use this contract to resolve disputes equivalent to DVM voting on mainnet. Once requested, anyone can push desired test price through this mock oracle contract.TestnetERC20
: Unless existing default currency was provided the script will have deployed this new token that is whitelisted as a bonding currency. Anyone can mint new tokens by calling itsallocateTo(address ownerAddress, uint256 value)
method.OptimisticOracleV3
: Optimistic Oracle that resolves assertions made by integrating contracts.
Resolving dispute requests
Whenever the assertion is disputed, Optimistic Oracle V3 calls requestPrice
method on the Oracle that triggers DVM vote on mainnet. In the sandboxed environment this would resolve to MockOracleAncillary
contract instead.
The disputed request is uniquely identified by its identifier, timestamp and ancillary data that should be referenced by the testing developer pushing resolved price to the mocked oracle. The MockOracleAncillary
contract will emit PriceRequestAdded
event with following parameters:
address indexed requester
: Address of the calling contract (Optimistic Oracle V3 in the sandboxed setup).bytes32 indexed identifier
: Identifier referencing the rules on how the request should be resolved. By default Optimistic Oracle V3 usesASSERT_TRUTH
identifier unless the integrating contract provided other value.uint256 time
: Optimistic Oracle V3 will set this to timestamp when the original assertion was made.bytes ancillaryData
: Optimistic Oracle V3 will put theassertionId
and address of the asserter referencing the disputed assertion.bytes32 indexed requestId
: This is hashed value of identifier, time and ancillary data provided by theMockOracleAncillary
contract just as convenient method to resolve request by one parameter instead of three separate parameters.
Note that production voting contract on mainnet emits this differently and above PriceRequestAdded
is provided only as a convenience for developers when interacting with the MockOracleAncillary
contract in their testing environment.
MockOracleAncillary
contract provides two alternative methods for testing developers to resolve request:
pushPrice(bytes32 identifier, uint256 time, bytes memory ancillaryData, int256 price)
where request is referenced by its individual parameters.pushPriceByRequestId(bytes32 requestId, int256 price)
where request is referenced by the hashed value of its identifying parameters.
While testing developer can pass any int256
price value, Optimistic Oracle V3 can only interpret value of 1e18
to represent truthful assertion. Any other value would settle assertion as being false. Also note that MockOracleAncillary
contract will only accept the first pushed price to resolve a given request.
Example dispute flow
As an illustration to the section above this example walks through resolving disputed assertion with cast
tool from Foundry. This also requires jq
being installed for parsing returned values.
Just for the sake of simplicity set MINIMUM_BOND
environment variable to 0
when running forge script
command as discussed in the sandbox deployment section. This would allow to skip minting and approving assertion/dispute bonds. Take a note of deployed contracts log and export Optimistic Oracle V3 address to OOV3_ADDRESS
and MockOracleAncillary
address to MOCK_ORACLE_ADDRESS
environment variables.
Also to keep this simple perform all steps from the same address:
Start with generating test assertion and grab the resulting assertionId
emitted by Optimistic Oracle V3 (corresponds to topic index 1
in the AssertionMade
event):
Dispute the above assertion and grab the resulting requestId
emitted by MockOracleAncillary
(corresponds to topic index 3
in the PriceRequestAdded
event):
Now resolve the disputed assertion as truthful by pushing 1e18
as price to MockOracleAncillary
contract:
This allows us to settle the assertion at Optimistic Oracle V3:
Finally, you can verify that Optimistic Oracle V3 has correctly settled the assertion (this should return true
):
Further sandbox configuration
The deployment script documented in the section above covers most common use cases and should be sufficient to test example contracts from the Optimistic Oracle V3 integration quickstart repository. Though, when developing your own integrating contracts it might be required to further configure the sandboxed oracle environment.
Whitelisting of bonding currencies
In case the integrating contract requires handling assertion bonds in multiple currencies all of them should be approved at the AddressWhitelist
contract. On production this should go through UMA governance while in the sandboxed environment the deployer owns this contract and can call addToWhitelist
method directly. Assuming the address of AddressWhitelist
contract is exported to ADDRESS_WHITELIST
and required bonding currency is exported to BONDING_CURRENCY
environment variables, this can be done by:
In order to test the scenario on how the integrating contracts would behave if UMA governance removed support for a particular bonding currency, you can test this by calling removeFromWhitelist
method on the AddressWhitelist
contract:
Note that Optimistic Oracle V3 is caching whitelisted bonding currencies. Hence, before testing impact on the integrating contracts somebody should sync the contract cache (anyone has authority to do this):
Changing the final fee
In case the UMA governance was to change the configured final fee for a particular bonding currency this would also change the minimum assertion bond required by Optimistic Oracle V3. In order to test such impact on integrating contracts in the testing environment, the deployer would need to call setFinalFee
on the Store
contract (exported as STORE_ADDRESS
). E.g. to set final fee to 1000e18
, you would call:
Again, before testing impact on integrating contracts someone would need to sync new final fee at the Optimistic Oracle V3:
Whitelisting of identifiers
If the integrating contract plans to make assertions with multiple identifiers, the developer would need to add them to IdentifierWhitelist
contract (exported as IDENTIFIER_ADDRESS
) in the sandboxed environment, e.g. adding CUSTOM_IDENTIFIER
:
In order to test the scenario on how the integrating contracts would behave if UMA governance removed support for a particular identifier, you can test this by calling removeSupportedIdentifier
method on the IdentifierWhitelist
contract:
Note that Optimistic Oracle V3 is caching whitelisted identifiers. Hence, before testing impact on the integrating contracts somebody should sync the contract cache (anyone has authority to do this):
Last updated