Skip to content

Commit

Permalink
add set oracle (#311)
Browse files Browse the repository at this point in the history
  • Loading branch information
Spablob authored Nov 22, 2024
1 parent 6aa8573 commit 2ce76ce
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { IOOV3Callbacks } from "./IOOV3Callbacks.sol";

/// @title Arbitration Policy UMA Interface
interface IArbitrationPolicyUMA is IArbitrationPolicy, IOOV3Callbacks {
/// @notice Emitted when the OOV3 address is set
/// @param oov3 The address of the OOV3
event OOV3Set(address oov3);

/// @notice Emitted when liveness is set
/// @param minLiveness The minimum liveness value
/// @param maxLiveness The maximum liveness value
Expand Down Expand Up @@ -40,6 +44,10 @@ interface IArbitrationPolicyUMA is IArbitrationPolicy, IOOV3Callbacks {
/// @param counterEvidenceHash The counter evidence hash
event AssertionDisputed(bytes32 assertionId, bytes32 counterEvidenceHash);

/// @notice Sets the OOV3 address
/// @param oov3 The address of the OOV3
function setOOV3(address oov3) external;

/// @notice Sets the liveness for UMA disputes
/// @param minLiveness The minimum liveness value
/// @param maxLiveness The maximum liveness value
Expand Down Expand Up @@ -68,6 +76,9 @@ interface IArbitrationPolicyUMA is IArbitrationPolicy, IOOV3Callbacks {
/// @notice Returns the percentage of liveness time the IP owner has priority to respond to a dispute
function ipOwnerTimePercent() external view returns (uint32);

/// @notice Returns the OOV3 address
function oov3() external view returns (address);

/// @notice Returns the maximum bond for a given token for UMA disputes
/// @param token The token address
function maxBonds(address token) external view returns (uint256);
Expand Down
46 changes: 29 additions & 17 deletions contracts/modules/dispute/policies/UMA/ArbitrationPolicyUMA.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,11 @@ contract ArbitrationPolicyUMA is
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
address public immutable DISPUTE_MODULE;

/// @notice OOV3 address
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
IOOV3 public immutable OOV3;

/// @dev Storage structure for the ArbitrationPolicyUMA
/// @param minLiveness The minimum liveness value
/// @param maxLiveness The maximum liveness value
/// @param ipOwnerTimePercent The percentage of liveness time the IP owner has priority to respond to a dispute
/// @param oov3 The address of the OOV3
/// @param maxBonds The maximum bond size for each token
/// @param disputeIdToAssertionId The mapping of dispute id to assertion id
/// @param assertionIdToDisputeId The mapping of assertion id to dispute id
Expand All @@ -47,6 +44,7 @@ contract ArbitrationPolicyUMA is
uint64 minLiveness;
uint64 maxLiveness;
uint32 ipOwnerTimePercent;
IOOV3 oov3;
mapping(address token => uint256 maxBondSize) maxBonds;
mapping(uint256 disputeId => bytes32 assertionId) disputeIdToAssertionId;
mapping(bytes32 assertionId => uint256 disputeId) assertionIdToDisputeId;
Expand All @@ -65,14 +63,11 @@ contract ArbitrationPolicyUMA is

/// Constructor
/// @param disputeModule The address of the dispute module
/// @param oov3 The address of the OOV3
/// @custom:oz-upgrades-unsafe-allow constructor
constructor(address disputeModule, address oov3) {
constructor(address disputeModule) {
if (disputeModule == address(0)) revert Errors.ArbitrationPolicyUMA__ZeroDisputeModule();
if (oov3 == address(0)) revert Errors.ArbitrationPolicyUMA__ZeroOOV3();

DISPUTE_MODULE = disputeModule;
OOV3 = IOOV3(oov3);
_disableInitializers();
}

Expand All @@ -86,6 +81,17 @@ contract ArbitrationPolicyUMA is
__UUPSUpgradeable_init();
}

/// @notice Sets the OOV3 address
/// @param oov3 The address of the OOV3
function setOOV3(address oov3) external restricted {
if (oov3 == address(0)) revert Errors.ArbitrationPolicyUMA__ZeroOOV3();

ArbitrationPolicyUMAStorage storage $ = _getArbitrationPolicyUMAStorage();
$.oov3 = IOOV3(oov3);

emit OOV3Set(oov3);
}

/// @notice Sets the liveness for UMA disputes
/// @param minLiveness The minimum liveness value
/// @param maxLiveness The maximum liveness value
Expand Down Expand Up @@ -130,10 +136,11 @@ contract ArbitrationPolicyUMA is
if (bond > $.maxBonds[currency]) revert Errors.ArbitrationPolicyUMA__BondAboveMax();

IERC20 currencyToken = IERC20(currency);
IOOV3 oov3 = $.oov3;
currencyToken.safeTransferFrom(caller, address(this), bond);
currencyToken.safeIncreaseAllowance(address(OOV3), bond);
currencyToken.safeIncreaseAllowance(address(oov3), bond);

bytes32 assertionId = OOV3.assertTruth(
bytes32 assertionId = oov3.assertTruth(
claim,
caller, // asserter
address(this), // callbackRecipient
Expand Down Expand Up @@ -193,7 +200,7 @@ contract ArbitrationPolicyUMA is
if (parentDisputeId > 0) revert Errors.ArbitrationPolicyUMA__CannotDisputeAssertionIfTagIsInherited();

// Check if the address can dispute the assertion depending on the liveness and the elapsed time
IOOV3.Assertion memory assertion = OOV3.getAssertion(assertionId);
IOOV3.Assertion memory assertion = $.oov3.getAssertion(assertionId);
uint64 liveness = assertion.expirationTime - assertion.assertionTime;
uint64 elapsedTime = uint64(block.timestamp) - assertion.assertionTime;
bool inIpOwnerTimeWindow = elapsedTime <= (liveness * $.ipOwnerTimePercent) / MAX_PERCENT;
Expand All @@ -207,10 +214,11 @@ contract ArbitrationPolicyUMA is
$.counterEvidenceHashes[assertionId] = counterEvidenceHash;

IERC20 currencyToken = IERC20(assertion.currency);
IOOV3 oov3 = $.oov3;
currencyToken.safeTransferFrom(msg.sender, address(this), assertion.bond);
currencyToken.safeIncreaseAllowance(address(OOV3), assertion.bond);
currencyToken.safeIncreaseAllowance(address(oov3), assertion.bond);

OOV3.disputeAssertion(assertionId, msg.sender);
oov3.disputeAssertion(assertionId, msg.sender);

emit AssertionDisputed(assertionId, counterEvidenceHash);
}
Expand All @@ -219,9 +227,9 @@ contract ArbitrationPolicyUMA is
/// @param assertionId The resolved assertion identifier
/// @param assertedTruthfully Indicates if the assertion was resolved as truthful or not
function assertionResolvedCallback(bytes32 assertionId, bool assertedTruthfully) external nonReentrant {
if (msg.sender != address(OOV3)) revert Errors.ArbitrationPolicyUMA__NotOOV3();

ArbitrationPolicyUMAStorage storage $ = _getArbitrationPolicyUMAStorage();
if (msg.sender != address($.oov3)) revert Errors.ArbitrationPolicyUMA__NotOOV3();

uint256 disputeId = $.assertionIdToDisputeId[assertionId];

IDisputeModule(DISPUTE_MODULE).setDisputeJudgement(disputeId, assertedTruthfully, "");
Expand All @@ -230,9 +238,8 @@ contract ArbitrationPolicyUMA is
/// @notice OOV3 callback function for when an assertion is disputed
/// @param assertionId The disputed assertion identifier
function assertionDisputedCallback(bytes32 assertionId) external {
if (msg.sender != address(OOV3)) revert Errors.ArbitrationPolicyUMA__NotOOV3();

ArbitrationPolicyUMAStorage storage $ = _getArbitrationPolicyUMAStorage();
if (msg.sender != address($.oov3)) revert Errors.ArbitrationPolicyUMA__NotOOV3();
if ($.counterEvidenceHashes[assertionId] == bytes32(0)) revert Errors.ArbitrationPolicyUMA__NoCounterEvidence();
}

Expand All @@ -256,6 +263,11 @@ contract ArbitrationPolicyUMA is
return _getArbitrationPolicyUMAStorage().ipOwnerTimePercent;
}

/// @notice Returns the OOV3 address
function oov3() external view returns (address) {
return address(_getArbitrationPolicyUMAStorage().oov3);
}

/// @notice Returns the maximum bond for a given token for UMA disputes
/// @param token The token address
function maxBonds(address token) external view returns (uint256) {
Expand Down
5 changes: 3 additions & 2 deletions script/foundry/utils/DeployHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ contract DeployHelper is Script, BroadcastManager, JsonDeploymentHandler, Storag
MAX_ROYALTY_APPROVAL = maxRoyaltyApproval_;
TREASURY_ADDRESS = treasury_;
ipGraphACL = IPGraphACL(ipGraphACL_);
oov3 = address(1); // mock address replaced below depending on chainid
oov3 = address(1000); // mock address replaced below depending on chainid
/// @dev USDC addresses are fetched from
/// (mainnet) https://developers.circle.com/stablecoins/docs/usdc-on-main-networks
/// (testnet) https://developers.circle.com/stablecoins/docs/usdc-on-test-networks
Expand Down Expand Up @@ -523,7 +523,7 @@ contract DeployHelper is Script, BroadcastManager, JsonDeploymentHandler, Storag
//

_predeploy("ArbitrationPolicyUMA");
impl = address(new ArbitrationPolicyUMA(address(disputeModule), oov3));
impl = address(new ArbitrationPolicyUMA(address(disputeModule)));
arbitrationPolicyUMA = ArbitrationPolicyUMA(
TestProxyHelper.deployUUPSProxy(
create3Deployer,
Expand Down Expand Up @@ -759,6 +759,7 @@ contract DeployHelper is Script, BroadcastManager, JsonDeploymentHandler, Storag
disputeModule.whitelistArbitrationPolicy(address(arbitrationPolicyUMA), true);
disputeModule.whitelistArbitrationRelayer(address(arbitrationPolicyUMA), address(arbitrationPolicyUMA), true);
disputeModule.setBaseArbitrationPolicy(address(arbitrationPolicyUMA));
arbitrationPolicyUMA.setOOV3(address(oov3));
arbitrationPolicyUMA.setLiveness(30 days, 365 days, 66_666_666);
arbitrationPolicyUMA.setMaxBond(address(erc20), 25000e18); // 25k USD max bond
disputeModule.setArbitrationPolicyCooldown(7 days);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { MockERC20 } from "test/foundry/mocks/token/MockERC20.sol";
import { TestProxyHelper } from "test/foundry/utils/TestProxyHelper.sol";

contract ArbitrationPolicyUMATest is BaseTest {
event OOV3Set(address oov3);
event LivenessSet(uint64 minLiveness, uint64 maxLiveness, uint32 ipOwnerTimePercent);
event MaxBondSet(address token, uint256 maxBond);
event DisputeRaisedUMA(
Expand Down Expand Up @@ -70,7 +71,7 @@ contract ArbitrationPolicyUMATest is BaseTest {
);

// deploy arbitration policy UMA
address newArbitrationPolicyUMAImpl = address(new ArbitrationPolicyUMA(address(newDisputeModule), newOOV3));
address newArbitrationPolicyUMAImpl = address(new ArbitrationPolicyUMA(address(newDisputeModule)));
newArbitrationPolicyUMA = ArbitrationPolicyUMA(
TestProxyHelper.deployUUPSProxy(
newArbitrationPolicyUMAImpl,
Expand All @@ -79,6 +80,7 @@ contract ArbitrationPolicyUMATest is BaseTest {
);

// setup UMA parameters
newArbitrationPolicyUMA.setOOV3(newOOV3);
newArbitrationPolicyUMA.setLiveness(30 days, 365 days, 66_666_666);
newArbitrationPolicyUMA.setMaxBond(susd, 25000e18); // 25k USD max bond

Expand All @@ -101,12 +103,22 @@ contract ArbitrationPolicyUMATest is BaseTest {

function test_ArbitrationPolicyUMA_constructor_revert_ZeroDisputeModule() public {
vm.expectRevert(Errors.ArbitrationPolicyUMA__ZeroDisputeModule.selector);
new ArbitrationPolicyUMA(address(0), address(1));
new ArbitrationPolicyUMA(address(0));
}

function test_ArbitrationPolicyUMA_constructor_revert_ZeroOOV3() public {
function test_ArbitrationPolicyUMA_setOOV3_revert_ZeroOOV3() public {
vm.expectRevert(Errors.ArbitrationPolicyUMA__ZeroOOV3.selector);
new ArbitrationPolicyUMA(address(1), address(0));
newArbitrationPolicyUMA.setOOV3(address(0));
}

function test_ArbitrationPolicyUMA_setOOV3() public {
address testOOV3 = address(1000);
vm.expectEmit(true, true, true, true);
emit OOV3Set(testOOV3);

newArbitrationPolicyUMA.setOOV3(testOOV3);

assertEq(newArbitrationPolicyUMA.oov3(), testOOV3);
}

function test_ArbitrationPolicyUMA_setLiveness_revert_ZeroMinLiveness() public {
Expand Down

0 comments on commit 2ce76ce

Please sign in to comment.