-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
- Loading branch information
Showing
3 changed files
with
110 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity 0.8.17; | ||
|
||
import {Ownable} from "openzeppelin-contracts/contracts/access/Ownable.sol"; | ||
import {MutableUnlockersController} from "../controllers/MutableUnlockersController.sol"; | ||
import {CoinbaseSourceAdapter} from "../adapters/source-adapters/CoinbaseSourceAdapter.sol"; | ||
import {ChainlinkDestinationAdapter} from "../adapters/destination-adapters/ChainlinkDestinationAdapter.sol"; | ||
import {IAggregatorV3SourceCoinbase} from "../interfaces/coinbase/IAggregatorV3SourceCoinbase.sol"; | ||
import {BaseFactory} from "./BaseFactory.sol"; | ||
|
||
/** | ||
* @title OvalCoinbase is the recommended Oval Coinbase contract that allows Oval to extract OEV generated by | ||
* Coinbase usage. | ||
*/ | ||
contract OvalCoinbase is MutableUnlockersController, CoinbaseSourceAdapter, ChainlinkDestinationAdapter { | ||
constructor( | ||
IAggregatorV3SourceCoinbase source, | ||
string memory ticker, | ||
address[] memory unlockers, | ||
uint256 lockWindow, | ||
uint256 maxTraversal, | ||
address owner | ||
) | ||
CoinbaseSourceAdapter(source, ticker) | ||
MutableUnlockersController(lockWindow, maxTraversal, unlockers) | ||
ChainlinkDestinationAdapter(18) | ||
{ | ||
_transferOwnership(owner); | ||
} | ||
} | ||
|
||
/** | ||
* @title StandardCoinbaseFactory is the recommended factory for use cases that want a Coinbase source and Chainlink | ||
* interface. | ||
* @dev This is the best factory for most use cases, but there are other variants that may be needed if different | ||
* mutability choices are desired. | ||
*/ | ||
contract StandardCoinbaseFactory is Ownable, BaseFactory { | ||
IAggregatorV3SourceCoinbase immutable SOURCE; | ||
|
||
constructor(IAggregatorV3SourceCoinbase source, uint256 maxTraversal, address[] memory _defaultUnlockers) | ||
BaseFactory(maxTraversal, _defaultUnlockers) | ||
{ | ||
SOURCE = source; | ||
} | ||
|
||
/** | ||
* @notice Creates the Coinbase Oval instance. | ||
* @param ticker the Coinbase oracle's ticker. | ||
* @param lockWindow the lockWindow used for this Oval instance. This is the length of the window | ||
* for the Oval auction to be run and, thus, the maximum time that prices will be delayed. | ||
* @return oval deployed oval address. | ||
*/ | ||
function create(string memory ticker, uint256 lockWindow) external returns (address oval) { | ||
oval = address(new OvalCoinbase(SOURCE, ticker, defaultUnlockers, lockWindow, MAX_TRAVERSAL, owner())); | ||
emit OvalDeployed(msg.sender, oval, lockWindow, MAX_TRAVERSAL, owner(), defaultUnlockers); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity 0.8.17; | ||
|
||
import {StandardCoinbaseFactory} from "../../src/factories/StandardCoinbaseFactory.sol"; | ||
import {OvalCoinbase} from "../../src/factories/StandardCoinbaseFactory.sol"; | ||
import {IAggregatorV3SourceCoinbase} from "../../src/interfaces/coinbase/IAggregatorV3SourceCoinbase.sol"; | ||
import {MockChainlinkV3Aggregator} from "../mocks/MockChainlinkV3Aggregator.sol"; | ||
import {CommonTest} from "../Common.sol"; | ||
|
||
contract StandardCoinbaseFactoryTest is CommonTest { | ||
StandardCoinbaseFactory factory; | ||
IAggregatorV3SourceCoinbase mockSource; | ||
address[] unlockers; | ||
uint256 lockWindow = 300; | ||
uint256 maxTraversal = 15; | ||
string ticker = "test ticker"; | ||
|
||
function setUp() public { | ||
mockSource = IAggregatorV3SourceCoinbase(address(new MockChainlinkV3Aggregator(8, 420))); | ||
unlockers.push(address(0x123)); | ||
factory = new StandardCoinbaseFactory(mockSource, maxTraversal, unlockers); | ||
} | ||
|
||
function testCreateMutableUnlockerOvalCoinbase() public { | ||
address created = factory.create(ticker, lockWindow); | ||
|
||
assertTrue(created != address(0)); // Check if the address is set, non-zero. | ||
|
||
OvalCoinbase instance = OvalCoinbase(created); | ||
assertTrue(instance.lockWindow() == lockWindow); | ||
assertTrue(instance.maxTraversal() == maxTraversal); | ||
|
||
// Check if the unlockers are set correctly | ||
for (uint256 i = 0; i < unlockers.length; i++) { | ||
assertTrue(instance.canUnlock(unlockers[i], 0)); | ||
} | ||
assertFalse(instance.canUnlock(address(0x456), 0)); // Check if a random address cannot unlock | ||
} | ||
|
||
function testOwnerCanChangeUnlockers() public { | ||
address created = factory.create(ticker, lockWindow); | ||
OvalCoinbase instance = OvalCoinbase(created); | ||
|
||
address newUnlocker = address(0x789); | ||
instance.setUnlocker(newUnlocker, true); // Correct method to add unlockers | ||
assertTrue(instance.canUnlock(newUnlocker, 0)); | ||
|
||
instance.setUnlocker(address(0x123), false); // Correct method to remove unlockers | ||
assertFalse(instance.canUnlock(address(0x123), 0)); | ||
} | ||
} |