Skip to content

Commit

Permalink
feat(extension): Add OptimisticAuctionRebalanceExtension (#156)
Browse files Browse the repository at this point in the history
* Initialize OptimisticAuctionRebalance module from Global version and fix compilation issues

* Add AssetAllowList to BaseOptimisticRebalanceExtension

* Use extisting AuctionRebalanceExtension

* Only allowed assets as new components

* Port tests from global version

* smol fix

* PR Feedback round 2

* PR Feedback round 3

* Simplify constructor tests

* Copy unit tests and run integrated with existing dseth deployment

* Test failing with unsupported identifier error

* All tests passing against uma deployed oracle

* Set block number individually in test

* Add isOpen boolean gate

* Set isOpen to false after starting rebalance

* Add onlyIfOpen modifier to startRebalance function

* Refactor / extend integration tests

* Disable locking set token

* Adjust tests

* Add V1 suffix

* Remove shouldLockSetToken argument entirely from propose method

* Add events for updating the isOpen parameter

* chore(edits): UMA Extension Edits (#157)

* Add events for updating the isOpen parameter

* lintoor

* remove .only()

* lintoor

* fix AssetAllowList nits

* Run only new integration tests

* Fix unittests

* Add tests for require statements in proposeRebalance

* Add tests for emitted events

* Extend event emission test

* Adjust integration test to use index token as proposer collateral (currently failing)

* integration test test

* cleanups

* edit integration tests

* Test bond transfer and claim construction

* Fix unittest

---------

Co-authored-by: ckoopmann <[email protected]>

* Add comment with link to optimistic governor reference implementation of _constructClaim

* Additional tests arround asset allow list

* Additional tests to increase coverage

* Declare setToken and auctionModule as immutable

* Remove Proposal struct because we are only managing one product per extension

* Additional tests to trigger require statements in dispute callback

* Fix integration tests

* Update contracts/adapters/AuctionRebalanceExtension.sol

* integration test cleanups

* fix buy auction params

* Update contracts/adapters/OptimisticAuctionRebalanceExtensionV1.sol

* cleanups

* Dummy commit to retrigger CI

---------

Co-authored-by: pblivin0x <[email protected]>
Co-authored-by: Pranav Bhardwaj <[email protected]>
  • Loading branch information
3 people authored Jan 9, 2024
1 parent d5ab030 commit 3fc56f4
Show file tree
Hide file tree
Showing 18 changed files with 2,797 additions and 33 deletions.
5 changes: 3 additions & 2 deletions contracts/adapters/AuctionRebalanceExtension.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ contract AuctionRebalanceExtension is BaseExtension {

/* ============ State Variables ============ */

ISetToken public setToken;
IAuctionRebalanceModuleV1 public auctionModule; // AuctionRebalanceModuleV1
ISetToken public immutable setToken;
IAuctionRebalanceModuleV1 public immutable auctionModule; // AuctionRebalanceModuleV1

/* ============ Constructor ============ */

Expand Down Expand Up @@ -88,6 +88,7 @@ contract AuctionRebalanceExtension is BaseExtension {
uint256 _positionMultiplier
)
external
virtual
onlyOperator
{
address[] memory currentComponents = setToken.getComponents();
Expand Down
411 changes: 411 additions & 0 deletions contracts/adapters/OptimisticAuctionRebalanceExtensionV1.sol

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions contracts/interfaces/IIdentifierWhitelist.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.4;

interface IIdentifierWhitelist {
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event SupportedIdentifierAdded(bytes32 indexed identifier);
event SupportedIdentifierRemoved(bytes32 indexed identifier);

function addSupportedIdentifier(bytes32 identifier) external;
function isIdentifierSupported(bytes32 identifier) external view returns (bool);
function owner() external view returns (address);
function removeSupportedIdentifier(bytes32 identifier) external;
function renounceOwnership() external;
function transferOwnership(address newOwner) external;
}
11 changes: 10 additions & 1 deletion contracts/interfaces/OptimisticOracleV3Interface.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ interface OptimisticOracleV3Interface {
uint256 finalFee; // Final fee of the currency.
}

/**
* @notice Disputes an assertion. Depending on how the assertion was configured, this may either escalate to the UMA
* DVM or the configured escalation manager for arbitration.
* @dev The caller must approve this contract to spend at least bond amount of currency for the associated assertion.
* @param assertionId unique identifier for the assertion to dispute.
* @param disputer receives bonds back at settlement.
*/
function disputeAssertion(bytes32 assertionId, address disputer) external;

/**
* @notice Returns the default identifier used by the Optimistic Oracle V3.
* @return The default identifier.
Expand Down Expand Up @@ -167,4 +176,4 @@ interface OptimisticOracleV3Interface {
);

event AdminPropertiesSet(IERC20 defaultCurrency, uint64 defaultLiveness, uint256 burnedBondPercentage);
}
}
147 changes: 147 additions & 0 deletions contracts/lib/AssetAllowList.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
Copyright 2023 Index Coop
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache License, Version 2.0
*/

pragma solidity 0.6.10;
import { AddressArrayUtils } from "./AddressArrayUtils.sol";

/**
* @title AssetAllowList
* @author Index Coop
*
* Abstract contract that allows inheriting contracts to restrict the assets that can be traded to, wrapped to, or claimed
*/
abstract contract AssetAllowList {
using AddressArrayUtils for address[];

/* ============ Events ============ */

event AllowedAssetAdded(
address indexed _asset
);

event AllowedAssetRemoved(
address indexed _asset
);

event UseAssetAllowlistUpdated(
bool _status
);

/* ============ State Variables ============ */

// Boolean indicating wether to use asset allow list
bool public useAssetAllowlist;

// Mapping keeping track of allowed assets
mapping(address => bool) public assetAllowlist;

// List of allowed assets
address[] internal allowedAssets;

/* ============ Modifiers ============ */

modifier onlyAllowedAssets(address[] memory _assets) {
require(
_areAllowedAssets(_assets),
"Invalid asset"
);
_;
}

/* ============ Constructor ============ */

/**
* Set state variables and map asset pairs to their oracles
*
* @param _allowedAssets Array of allowed assets
* @param _useAssetAllowlist Bool indicating whether to use asset allow list
*/
constructor(address[] memory _allowedAssets, bool _useAssetAllowlist) public {
_addAllowedAssets(_allowedAssets);
_updateUseAssetAllowlist(_useAssetAllowlist);
}

/* ============ External Functions ============ */

function getAllowedAssets() external view returns(address[] memory) {
return allowedAssets;
}

/* ============ Internal Functions ============ */


/**
* Add new assets that can be traded to, wrapped to, or claimed
*
* @param _assets New asset to add
*/
function _addAllowedAssets(address[] memory _assets) internal {
for (uint256 i = 0; i < _assets.length; i++) {
address asset = _assets[i];

require(!assetAllowlist[asset], "Asset already added");

allowedAssets.push(asset);

assetAllowlist[asset] = true;

emit AllowedAssetAdded(asset);
}
}

/**
* Remove asset(s) so that it/they can't be traded to, wrapped to, or claimed
*
* @param _assets Asset(s) to remove
*/
function _removeAllowedAssets(address[] memory _assets) internal {
for (uint256 i = 0; i < _assets.length; i++) {
address asset = _assets[i];

require(assetAllowlist[asset], "Asset not already added");

allowedAssets.removeStorage(asset);

assetAllowlist[asset] = false;

emit AllowedAssetRemoved(asset);
}
}

/**
* Toggle useAssetAllowlist on and off. When false asset allowlist is ignored
* when true it is enforced.
*
* @param _useAssetAllowlist Bool indicating whether to use asset allow list
*/
function _updateUseAssetAllowlist(bool _useAssetAllowlist) internal {
useAssetAllowlist = _useAssetAllowlist;

emit UseAssetAllowlistUpdated(_useAssetAllowlist);
}

/// @notice Check that all assets in array are allowed to be treated
/// @dev ca be bypassed by setting the useAssetAllowlist to false (default)
function _areAllowedAssets(address[] memory _assets) internal view returns(bool) {
if (!useAssetAllowlist) { return true; }
for (uint256 i = 0; i < _assets.length; i++) {
if (!assetAllowlist[_assets[i]]) { return false; }
}
return true;
}
}
13 changes: 11 additions & 2 deletions contracts/mocks/OptimisticOracleV3Mock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,16 @@ interface callbackInterface {
* tradeoffs, enabling the notion of "sovereign security".
*/
contract OptimisticOracleV3Mock is OptimisticOracleV3Interface {
address public asserter;
// Mock implementation of defaultIdentifier
function defaultIdentifier() public view override returns (bytes32) {
return (bytes32("helloWorld"));
}

function setAsserter(address _asserter) public {
asserter = _asserter;
}

// Mock implementation of getAssertion
function getAssertion(bytes32 ) public view override returns (Assertion memory) {
return (Assertion({
Expand All @@ -36,7 +41,7 @@ contract OptimisticOracleV3Mock is OptimisticOracleV3Interface {
assertingCaller: address(0),
escalationManager: address(0)
}),
asserter: address(0),
asserter: asserter,
assertionTime: uint64(0),
settled: false,
currency: IERC20(address(0)),
Expand Down Expand Up @@ -80,6 +85,10 @@ contract OptimisticOracleV3Mock is OptimisticOracleV3Interface {
return (false);
}

function disputeAssertion(bytes32 assertionId, address disputer) external override {
revert("Not implemented");
}

// Mock implementation of getMinimumBond
function getMinimumBond(address ) public view override returns (uint256) {
return (uint256(0));
Expand All @@ -95,4 +104,4 @@ contract OptimisticOracleV3Mock is OptimisticOracleV3Interface {
callbackInterface(target).assertionResolvedCallback(assertionId, truthfully);
}

}
}
Loading

0 comments on commit 3fc56f4

Please sign in to comment.