Skip to content

Commit

Permalink
add coinbase
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
  • Loading branch information
mrice32 committed May 20, 2024
1 parent 871b815 commit fba78a1
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/factories/StandardChainlinkFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ contract OvalChainlink is MutableUnlockersController, ChainlinkSourceAdapter, Ch
)
ChainlinkSourceAdapter(source)
MutableUnlockersController(lockWindow, maxTraversal, unlockers)
ChainlinkDestinationAdapter(source.decimals())
ChainlinkDestinationAdapter(18)
{
_transferOwnership(owner);
}
Expand Down
58 changes: 58 additions & 0 deletions src/factories/StandardCoinbaseFactory.sol
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);
}
}
51 changes: 51 additions & 0 deletions test/unit/StandardCoinbaseFactory.sol
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));
}
}

0 comments on commit fba78a1

Please sign in to comment.