Skip to content

Commit

Permalink
Setter for protocol address
Browse files Browse the repository at this point in the history
  • Loading branch information
0xJem committed Feb 6, 2024
1 parent 294899f commit 7a1896a
Show file tree
Hide file tree
Showing 2 changed files with 214 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/AuctionHouse.sol
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,14 @@ abstract contract FeeManager is Owned {

token.safeTransfer(msg.sender, amount);
}

/// @notice Sets the protocol address
/// @dev Access controlled: only owner
///
/// @param protocol_ Address of the protocol
function setProtocol(address protocol_) external onlyOwner {
_protocol = protocol_;
}
}

/// @title Router
Expand Down
206 changes: 206 additions & 0 deletions test/AuctionHouse/setProtocol.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.19;

// Libraries
import {Test} from "forge-std/Test.sol";
import {ERC20} from "solmate/tokens/ERC20.sol";
import {IPermit2} from "src/lib/permit2/interfaces/IPermit2.sol";

// Mocks
import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol";
import {MockAtomicAuctionModule} from "test/modules/Auction/MockAtomicAuctionModule.sol";
import {Permit2User} from "test/lib/permit2/Permit2User.sol";

// Auctions
import {AuctionHouse, Router, FeeManager} from "src/AuctionHouse.sol";
import {Auction} from "src/modules/Auction.sol";
import {IHooks, IAllowlist, Auctioneer} from "src/bases/Auctioneer.sol";

// Modules
import {
Keycode,
toKeycode,
Veecode,
wrapVeecode,
fromVeecode,
WithModules,
Module
} from "src/modules/Modules.sol";

contract SetProtocolTest is Test, Permit2User {
MockERC20 internal baseToken;
MockERC20 internal quoteToken;
MockAtomicAuctionModule internal mockAuctionModule;

AuctionHouse internal auctionHouse;

address internal immutable protocol = address(0x2);
address internal immutable curator = address(0x3);
address internal immutable referrer = address(0x4);
address internal immutable auctionOwner = address(0x5);
address internal immutable recipient = address(0x6);
address internal immutable newProtocol = address(0x7);

uint256 internal aliceKey;
address internal alice;

uint96 internal lotId;

uint256 internal constant LOT_CAPACITY = 10e18;

uint256 internal constant AMOUNT_IN = 1e18;
uint256 internal AMOUNT_OUT;
uint256 internal curatorActualFee;
uint256 internal curatorMaxPotentialFee;

uint48 internal constant CURATOR_MAX_FEE = 100;
uint48 internal constant CURATOR_FEE = 90;

uint48 internal referrerFee;
uint48 internal protocolFee;

uint256 internal amountInLessFee;
uint256 internal amountInReferrerFee;
uint256 internal amountInProtocolFee;

Keycode internal auctionType = toKeycode("ATOM");

// Function parameters (can be modified)
Auctioneer.RoutingParams internal routingParams;
Auction.AuctionParams internal auctionParams;
Router.PurchaseParams internal purchaseParams;
uint256 internal approvalNonce;
bytes internal approvalSignature;
uint48 internal approvalDeadline;
uint256 internal derivativeTokenId;
bytes internal allowlistProof;

function setUp() external {
aliceKey = _getRandomUint256();
alice = vm.addr(aliceKey);

baseToken = new MockERC20("Base Token", "BASE", 18);
quoteToken = new MockERC20("Quote Token", "QUOTE", 18);

auctionHouse = new AuctionHouse(protocol, _PERMIT2_ADDRESS);
mockAuctionModule = new MockAtomicAuctionModule(address(auctionHouse));

auctionParams = Auction.AuctionParams({
start: uint48(block.timestamp),
duration: uint48(1 days),
capacityInQuote: false,
capacity: LOT_CAPACITY,
implParams: abi.encode("")
});

routingParams = Auctioneer.RoutingParams({
auctionType: auctionType,
baseToken: baseToken,
quoteToken: quoteToken,
curator: address(0),
hooks: IHooks(address(0)),
allowlist: IAllowlist(address(0)),
allowlistParams: abi.encode(""),
payoutData: abi.encode(""),
derivativeType: toKeycode(""),
derivativeParams: abi.encode("")
});

// Install the auction module
auctionHouse.installModule(mockAuctionModule);

// Create an auction
vm.prank(auctionOwner);
lotId = auctionHouse.auction(routingParams, auctionParams);

// Fees
referrerFee = 1000;
protocolFee = 2000;
auctionHouse.setFee(auctionType, FeeManager.FeeType.Protocol, protocolFee);
auctionHouse.setFee(auctionType, FeeManager.FeeType.Referrer, referrerFee);
auctionHouse.setFee(auctionType, FeeManager.FeeType.MaxCurator, CURATOR_MAX_FEE);
curatorMaxPotentialFee = CURATOR_FEE * LOT_CAPACITY / 1e5;

amountInReferrerFee = (AMOUNT_IN * referrerFee) / 1e5;
amountInProtocolFee = (AMOUNT_IN * protocolFee) / 1e5;
amountInLessFee = AMOUNT_IN - amountInReferrerFee - amountInProtocolFee;

// 1:1 exchange rate
AMOUNT_OUT = amountInLessFee;

// Purchase parameters
purchaseParams = Router.PurchaseParams({
recipient: recipient,
referrer: referrer,
lotId: lotId,
amount: AMOUNT_IN,
minAmountOut: AMOUNT_OUT,
auctionData: bytes(""),
allowlistProof: allowlistProof,
permit2Data: bytes("")
});
}

// ===== Modifiers ===== //

modifier givenProtocolAddressIsSet(address protocol_) {
auctionHouse.setProtocol(protocol_);
_;
}

modifier givenPurchase(uint256 amount_) {
// Mint base tokens
baseToken.mint(auctionOwner, LOT_CAPACITY);

// Approve spending
vm.prank(auctionOwner);
baseToken.approve(address(auctionHouse), LOT_CAPACITY);

// Mint quote tokens
quoteToken.mint(alice, amount_);

// Approve spending
vm.prank(alice);
quoteToken.approve(address(auctionHouse), amount_);

// Purchase
vm.prank(alice);
auctionHouse.purchase(purchaseParams);
_;
}

// ===== Tests ===== //

// [X] when caller is not the owner
// [X] it reverts
// [X] it sets the protocol address

function test_unauthorized() public {
// Expect revert
vm.expectRevert("UNAUTHORIZED");

// Call
vm.prank(alice);
auctionHouse.setProtocol(newProtocol);
}

function test_whenAddressIsNew()
public
givenProtocolAddressIsSet(newProtocol)
givenPurchase(AMOUNT_IN)
{
// Previous balance
uint256 previousBalance = quoteToken.balanceOf(newProtocol);

// Claim rewards
// As the protocol address is private, we cannot check that it was changed. But we can check that rewards were accrued.
vm.prank(newProtocol);
auctionHouse.claimRewards(address(quoteToken));

// Check new balance
assertEq(quoteToken.balanceOf(newProtocol), previousBalance + amountInProtocolFee);

// Check rewards
assertEq(auctionHouse.rewards(newProtocol, quoteToken), 0);
}
}

0 comments on commit 7a1896a

Please sign in to comment.