Skip to content

Commit 3fc56f4

Browse files
ckoopmannpblivin0x
andauthored
feat(extension): Add OptimisticAuctionRebalanceExtension (#156)
* 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]>
1 parent d5ab030 commit 3fc56f4

18 files changed

+2797
-33
lines changed

contracts/adapters/AuctionRebalanceExtension.sol

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ contract AuctionRebalanceExtension is BaseExtension {
4949

5050
/* ============ State Variables ============ */
5151

52-
ISetToken public setToken;
53-
IAuctionRebalanceModuleV1 public auctionModule; // AuctionRebalanceModuleV1
52+
ISetToken public immutable setToken;
53+
IAuctionRebalanceModuleV1 public immutable auctionModule; // AuctionRebalanceModuleV1
5454

5555
/* ============ Constructor ============ */
5656

@@ -88,6 +88,7 @@ contract AuctionRebalanceExtension is BaseExtension {
8888
uint256 _positionMultiplier
8989
)
9090
external
91+
virtual
9192
onlyOperator
9293
{
9394
address[] memory currentComponents = setToken.getComponents();

contracts/adapters/OptimisticAuctionRebalanceExtensionV1.sol

Lines changed: 411 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.4;
3+
4+
interface IIdentifierWhitelist {
5+
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
6+
event SupportedIdentifierAdded(bytes32 indexed identifier);
7+
event SupportedIdentifierRemoved(bytes32 indexed identifier);
8+
9+
function addSupportedIdentifier(bytes32 identifier) external;
10+
function isIdentifierSupported(bytes32 identifier) external view returns (bool);
11+
function owner() external view returns (address);
12+
function removeSupportedIdentifier(bytes32 identifier) external;
13+
function renounceOwnership() external;
14+
function transferOwnership(address newOwner) external;
15+
}

contracts/interfaces/OptimisticOracleV3Interface.sol

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ interface OptimisticOracleV3Interface {
3939
uint256 finalFee; // Final fee of the currency.
4040
}
4141

42+
/**
43+
* @notice Disputes an assertion. Depending on how the assertion was configured, this may either escalate to the UMA
44+
* DVM or the configured escalation manager for arbitration.
45+
* @dev The caller must approve this contract to spend at least bond amount of currency for the associated assertion.
46+
* @param assertionId unique identifier for the assertion to dispute.
47+
* @param disputer receives bonds back at settlement.
48+
*/
49+
function disputeAssertion(bytes32 assertionId, address disputer) external;
50+
4251
/**
4352
* @notice Returns the default identifier used by the Optimistic Oracle V3.
4453
* @return The default identifier.
@@ -167,4 +176,4 @@ interface OptimisticOracleV3Interface {
167176
);
168177

169178
event AdminPropertiesSet(IERC20 defaultCurrency, uint64 defaultLiveness, uint256 burnedBondPercentage);
170-
}
179+
}

contracts/lib/AssetAllowList.sol

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*
2+
Copyright 2023 Index Coop
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
16+
SPDX-License-Identifier: Apache License, Version 2.0
17+
*/
18+
19+
pragma solidity 0.6.10;
20+
import { AddressArrayUtils } from "./AddressArrayUtils.sol";
21+
22+
/**
23+
* @title AssetAllowList
24+
* @author Index Coop
25+
*
26+
* Abstract contract that allows inheriting contracts to restrict the assets that can be traded to, wrapped to, or claimed
27+
*/
28+
abstract contract AssetAllowList {
29+
using AddressArrayUtils for address[];
30+
31+
/* ============ Events ============ */
32+
33+
event AllowedAssetAdded(
34+
address indexed _asset
35+
);
36+
37+
event AllowedAssetRemoved(
38+
address indexed _asset
39+
);
40+
41+
event UseAssetAllowlistUpdated(
42+
bool _status
43+
);
44+
45+
/* ============ State Variables ============ */
46+
47+
// Boolean indicating wether to use asset allow list
48+
bool public useAssetAllowlist;
49+
50+
// Mapping keeping track of allowed assets
51+
mapping(address => bool) public assetAllowlist;
52+
53+
// List of allowed assets
54+
address[] internal allowedAssets;
55+
56+
/* ============ Modifiers ============ */
57+
58+
modifier onlyAllowedAssets(address[] memory _assets) {
59+
require(
60+
_areAllowedAssets(_assets),
61+
"Invalid asset"
62+
);
63+
_;
64+
}
65+
66+
/* ============ Constructor ============ */
67+
68+
/**
69+
* Set state variables and map asset pairs to their oracles
70+
*
71+
* @param _allowedAssets Array of allowed assets
72+
* @param _useAssetAllowlist Bool indicating whether to use asset allow list
73+
*/
74+
constructor(address[] memory _allowedAssets, bool _useAssetAllowlist) public {
75+
_addAllowedAssets(_allowedAssets);
76+
_updateUseAssetAllowlist(_useAssetAllowlist);
77+
}
78+
79+
/* ============ External Functions ============ */
80+
81+
function getAllowedAssets() external view returns(address[] memory) {
82+
return allowedAssets;
83+
}
84+
85+
/* ============ Internal Functions ============ */
86+
87+
88+
/**
89+
* Add new assets that can be traded to, wrapped to, or claimed
90+
*
91+
* @param _assets New asset to add
92+
*/
93+
function _addAllowedAssets(address[] memory _assets) internal {
94+
for (uint256 i = 0; i < _assets.length; i++) {
95+
address asset = _assets[i];
96+
97+
require(!assetAllowlist[asset], "Asset already added");
98+
99+
allowedAssets.push(asset);
100+
101+
assetAllowlist[asset] = true;
102+
103+
emit AllowedAssetAdded(asset);
104+
}
105+
}
106+
107+
/**
108+
* Remove asset(s) so that it/they can't be traded to, wrapped to, or claimed
109+
*
110+
* @param _assets Asset(s) to remove
111+
*/
112+
function _removeAllowedAssets(address[] memory _assets) internal {
113+
for (uint256 i = 0; i < _assets.length; i++) {
114+
address asset = _assets[i];
115+
116+
require(assetAllowlist[asset], "Asset not already added");
117+
118+
allowedAssets.removeStorage(asset);
119+
120+
assetAllowlist[asset] = false;
121+
122+
emit AllowedAssetRemoved(asset);
123+
}
124+
}
125+
126+
/**
127+
* Toggle useAssetAllowlist on and off. When false asset allowlist is ignored
128+
* when true it is enforced.
129+
*
130+
* @param _useAssetAllowlist Bool indicating whether to use asset allow list
131+
*/
132+
function _updateUseAssetAllowlist(bool _useAssetAllowlist) internal {
133+
useAssetAllowlist = _useAssetAllowlist;
134+
135+
emit UseAssetAllowlistUpdated(_useAssetAllowlist);
136+
}
137+
138+
/// @notice Check that all assets in array are allowed to be treated
139+
/// @dev ca be bypassed by setting the useAssetAllowlist to false (default)
140+
function _areAllowedAssets(address[] memory _assets) internal view returns(bool) {
141+
if (!useAssetAllowlist) { return true; }
142+
for (uint256 i = 0; i < _assets.length; i++) {
143+
if (!assetAllowlist[_assets[i]]) { return false; }
144+
}
145+
return true;
146+
}
147+
}

contracts/mocks/OptimisticOracleV3Mock.sol

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,16 @@ interface callbackInterface {
2121
* tradeoffs, enabling the notion of "sovereign security".
2222
*/
2323
contract OptimisticOracleV3Mock is OptimisticOracleV3Interface {
24+
address public asserter;
2425
// Mock implementation of defaultIdentifier
2526
function defaultIdentifier() public view override returns (bytes32) {
2627
return (bytes32("helloWorld"));
2728
}
2829

30+
function setAsserter(address _asserter) public {
31+
asserter = _asserter;
32+
}
33+
2934
// Mock implementation of getAssertion
3035
function getAssertion(bytes32 ) public view override returns (Assertion memory) {
3136
return (Assertion({
@@ -36,7 +41,7 @@ contract OptimisticOracleV3Mock is OptimisticOracleV3Interface {
3641
assertingCaller: address(0),
3742
escalationManager: address(0)
3843
}),
39-
asserter: address(0),
44+
asserter: asserter,
4045
assertionTime: uint64(0),
4146
settled: false,
4247
currency: IERC20(address(0)),
@@ -80,6 +85,10 @@ contract OptimisticOracleV3Mock is OptimisticOracleV3Interface {
8085
return (false);
8186
}
8287

88+
function disputeAssertion(bytes32 assertionId, address disputer) external override {
89+
revert("Not implemented");
90+
}
91+
8392
// Mock implementation of getMinimumBond
8493
function getMinimumBond(address ) public view override returns (uint256) {
8594
return (uint256(0));
@@ -95,4 +104,4 @@ contract OptimisticOracleV3Mock is OptimisticOracleV3Interface {
95104
callbackInterface(target).assertionResolvedCallback(assertionId, truthfully);
96105
}
97106

98-
}
107+
}

0 commit comments

Comments
 (0)