Skip to content

Commit

Permalink
Add hard limits for protocol rewards. make setting renderer more generic
Browse files Browse the repository at this point in the history
  • Loading branch information
neokry committed Oct 27, 2023
1 parent de3e3b0 commit 11028af
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 65 deletions.
23 changes: 10 additions & 13 deletions addresses/84531.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,14 @@
"BuilderDAO": "0x7498e6e471f31e869f038D8DBffbDFdf650c3F95",
"WETH": "0x4200000000000000000000000000000000000006",
"CrossDomainMessenger": "0x4200000000000000000000000000000000000007",
"Manager": "0x0351045fda7eb52635d516f2a0ffc0b9d1d21f75",
"ManagerImpl": "0xb713fa8f71e0154d2bc867e491af2c2e4f6c5741",
"Auction": "0xbaafa316e549c21ae811ec39278f90e6bc770947",
"Token": "0x36d5157f02069a40969c7895fd3e21d0c2097dff",
"MirrorToken": "0x7AB6a3EB70ae18Afa72562f5D51BACea20a8AbBa",
"MetadataRenderer": "0x444ce208c0f0f6787d4fbaaa0657c2a0fd095eb6",
"Treasury": "0x44a2bb76be05c5086e626f5d7e5cbeb043c9d91d",
"Governor": "0x2eefd2e9fbb2ebc5c393f092bbdd90418521bbf1",
"ProtocolRewards": "0xb601cf7945e77d26111a4e41b82b0ac82e2be10c",
"ERC721RedeemMinter": "0x6cbd4119cc78df069673b34f42e643bffe3e473a",
"MerkleReserveMinter": "0xf2dcdd37bec020b07faff1014dd7b23db193f104",
"MigrationDeployer": "0xd49a4ef9d13ea17e6c84aa4ecf4565f9f05cdfd0",
"CollectionPlusDeployer": "0xa05e7d87e412b9c7d1e7fec77ed797517142e78a"
"ProtocolRewards": "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B",
"Manager": "0x2177ab5b03866ca31b5acd0b837d7fd54c7d2936",
"ManagerImpl": "0x7d09fcd78ded047e112060f66ce4d4ec7c59e0be",
"Auction": "0xc7f35eb5896aa32b4decbe7768c903db43a20044",
"Token": "0x209452d7b38a36b042967ab0d9c6366ae1242dca",
"MetadataRenderer": "0x4238d016947087d21e9959c628688b6b5a527adc",
"Treasury": "0x23cbb0637dfe7eec42202c885cbfe76c09c7c759",
"Governor": "0x11e646c27529af1a18e6977d909be90d0cf504f5",
"MerkleReserveMinter": "0x1991abb6d9613ae4e339a1a747a894201d5e4dae",
"MigrationDeployer": "0xfad4bd5777fb472609f97fcde9fb001f5c0dd506"
}
15 changes: 7 additions & 8 deletions deploys/84531.version2_core.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
Manager: 0x0351045fda7eb52635d516f2a0ffc0b9d1d21f75
Default Token implementation: 0x36d5157f02069a40969c7895fd3e21d0c2097dff
Protocol Rewards:0xb601cf7945e77d26111a4e41b82b0ac82e2be10c
Metadata Renderer implementation: 0x444ce208c0f0f6787d4fbaaa0657c2a0fd095eb6
Auction implementation: 0xbaafa316e549c21ae811ec39278f90e6bc770947
Treasury implementation: 0x44a2bb76be05c5086e626f5d7e5cbeb043c9d91d
Governor implementation: 0x2eefd2e9fbb2ebc5c393f092bbdd90418521bbf1
Manager implementation: 0xb713fa8f71e0154d2bc867e491af2c2e4f6c5741
Manager: 0x2177ab5b03866ca31b5acd0b837d7fd54c7d2936
Token implementation: 0x209452d7b38a36b042967ab0d9c6366ae1242dca
Metadata Renderer implementation: 0x4238d016947087d21e9959c628688b6b5a527adc
Auction implementation: 0xc7f35eb5896aa32b4decbe7768c903db43a20044
Treasury implementation: 0x23cbb0637dfe7eec42202c885cbfe76c09c7c759
Governor implementation: 0x11e646c27529af1a18e6977d909be90d0cf504f5
Manager implementation: 0x7d09fcd78ded047e112060f66ce4d4ec7c59e0be
6 changes: 2 additions & 4 deletions deploys/84531.version2_new.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
ERC721 Redeem Minter: 0x6cbd4119cc78df069673b34f42e643bffe3e473a
Merkle Reserve Minter: 0xf2dcdd37bec020b07faff1014dd7b23db193f104
Migration Deployer: 0xd49a4ef9d13ea17e6c84aa4ecf4565f9f05cdfd0
Collection Plus Deployer: 0xa05e7d87e412b9c7d1e7fec77ed797517142e78a
Merkle Reserve Minter: 0x1991abb6d9613ae4e339a1a747a894201d5e4dae
Migration Deployer: 0xfad4bd5777fb472609f97fcde9fb001f5c0dd506
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@
"prepublishOnly": "rm -rf ./dist && forge clean && mkdir -p ./dist/artifacts && yarn build && cp -R src dist && cp -R addresses dist",
"generate:interfaces": "forge script script/GetInterfaceIds.s.sol:GetInterfaceIds -vvvv",
"deploy:dao": "source .env && forge script script/DeployNewDAO.s.sol:SetupDaoScript --private-key $PRIVATE_KEY --broadcast --rpc-url $RPC_URL -vvvv",
"deploy:contracts-local": "source .env && forge script script/DeployContracts.s.sol:DeployContracts --private-key $PRIVATE_KEY --broadcast --rpc-url $RPC_URL",
"deploy:contracts-v2-local": "source .env && forge script script/DeployContractsV2.s.sol:DeployContracts --private-key $PRIVATE_KEY --broadcast --rpc-url $RPC_URL",
"deploy:contracts-v2-core": "source .env && forge script script/DeployV2Core.s.sol:DeployContracts --private-key $PRIVATE_KEY --rpc-url $RPC_URL --broadcast --verify --etherscan-api-key $ETHERSCAN_API_KEY",
"deploy:contracts-v2-new": "source .env && forge script script/DeployV2New.s.sol:DeployContracts --private-key $PRIVATE_KEY --rpc-url $RPC_URL --broadcast --verify --etherscan-api-key $ETHERSCAN_API_KEY",
"deploy:contracts-zora": "source .env && forge script script/DeployContracts.s.sol:DeployContracts --private-key $PRIVATE_KEY --rpc-url $RPC_URL --broadcast --verify --verifier blockscout --verifier-url https://explorer.zora.energy/api? -vvvv",
"deploy:local": "source .env && forge script script/DeployContracts.s.sol:DeployContracts --private-key $PRIVATE_KEY --broadcast --rpc-url $RPC_URL",
"deploy:v2-local": "source .env && forge script script/DeployContractsV2.s.sol:DeployContracts --private-key $PRIVATE_KEY --broadcast --rpc-url $RPC_URL",
"deploy:v2-core": "source .env && forge script script/DeployV2Core.s.sol:DeployContracts --private-key $PRIVATE_KEY --rpc-url $RPC_URL --broadcast --verify --etherscan-api-key $ETHERSCAN_API_KEY",
"deploy:v2-new": "source .env && forge script script/DeployV2New.s.sol:DeployContracts --private-key $PRIVATE_KEY --rpc-url $RPC_URL --broadcast --verify --etherscan-api-key $ETHERSCAN_API_KEY",
"deploy:zora": "source .env && forge script script/DeployContracts.s.sol:DeployContracts --private-key $PRIVATE_KEY --rpc-url $RPC_URL --broadcast --verify --verifier blockscout --verifier-url https://explorer.zora.energy/api? -vvvv",
"test": "echo 'temporarily skipping metadata tests, remove this when fixed' && forge test --no-match-test 'WithAddress' -vvv",
"typechain": "typechain --target=ethers-v5 'dist/artifacts/*/*.json' --out-dir dist/typechain",
"storage-inspect:check": "./script/storage-check.sh check Manager Auction Governor Treasury Token",
Expand Down
27 changes: 22 additions & 5 deletions src/auction/Auction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ import { VersionedContract } from "../VersionedContract.sol";
/// - NounsAuctionHouse.sol commit 2cbe6c7 - licensed under the BSD-3-Clause license.
/// - Zora V3 ReserveAuctionCoreEth module commit 795aeca - licensed under the GPL-3.0 license.
contract Auction is IAuction, VersionedContract, UUPS, Ownable, ReentrancyGuard, Pausable, AuctionStorageV1, AuctionStorageV2 {
/// ///
/// CONSTANTS ///
/// ///

/// @notice The basis points for 100%
uint256 private constant BPS_PER_100_PERCENT = 10_000;

/// @notice The maximum rewards percentage
uint256 private constant MAX_FOUNDER_REWARDS_BPS = 3_000;

/// ///
/// IMMUTABLES ///
/// ///
Expand Down Expand Up @@ -86,6 +96,9 @@ contract Auction is IAuction, VersionedContract, UUPS, Ownable, ReentrancyGuard,
// Ensure the caller is the contract manager
if (msg.sender != address(manager)) revert ONLY_MANAGER();

// Ensure the founder reward is not more than max
if (_founderRewardBps > MAX_FOUNDER_REWARDS_BPS) revert INVALID_REWARDS_CONFIG();

// Initialize the reentrancy guard
__ReentrancyGuard_init();

Expand Down Expand Up @@ -417,6 +430,10 @@ contract Auction is IAuction, VersionedContract, UUPS, Ownable, ReentrancyGuard,
/// @notice Updates the founder reward recipent address
/// @param reward The new founder reward settings
function setFounderReward(FounderReward calldata reward) external onlyOwner whenPaused {
// Ensure the reward is not more than max
if (reward.percentBps > MAX_FOUNDER_REWARDS_BPS) revert INVALID_REWARDS_CONFIG();

// Update the founder reward settings
founderReward = reward;

emit FounderRewardUpdated(reward);
Expand All @@ -442,12 +459,12 @@ contract Auction is IAuction, VersionedContract, UUPS, Ownable, ReentrancyGuard,
uint256 totalBPS = _founderRewardBps + referralBps + builderBps;

// Verify percentage is not more than 100
if (totalBPS >= 10_000) {
if (totalBPS >= BPS_PER_100_PERCENT) {
revert INVALID_REWARD_TOTAL();
}

// Calulate total rewards
split.totalRewards = (_finalBidAmount * totalBPS) / 10_000;
split.totalRewards = (_finalBidAmount * totalBPS) / BPS_PER_100_PERCENT;

// Set the recipients
split.recipients = new address[](3);
Expand All @@ -457,9 +474,9 @@ contract Auction is IAuction, VersionedContract, UUPS, Ownable, ReentrancyGuard,

// Calculate reward splits
split.amounts = new uint256[](3);
split.amounts[0] = (_finalBidAmount * _founderRewardBps) / 10_000;
split.amounts[1] = (_finalBidAmount * referralBps) / 10_000;
split.amounts[2] = (_finalBidAmount * builderBps) / 10_000;
split.amounts[0] = (_finalBidAmount * _founderRewardBps) / BPS_PER_100_PERCENT;
split.amounts[1] = (_finalBidAmount * referralBps) / BPS_PER_100_PERCENT;
split.amounts[2] = (_finalBidAmount * builderBps) / BPS_PER_100_PERCENT;

// Leave reasons empty
split.reasons = new bytes4[](3);
Expand Down
3 changes: 3 additions & 0 deletions src/auction/IAuction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ interface IAuction is IUUPS, IOwnable, IPausable {
/// @dev Thrown if the auction creation failed
error AUCTION_CREATE_FAILED_TO_LAUNCH();

/// @dev Reverts if caller is not the token owner
error INVALID_REWARDS_CONFIG();

/// @dev Thrown if the rewards total is greater than 100%
error INVALID_REWARD_TOTAL();

Expand Down
54 changes: 29 additions & 25 deletions src/deployers/L2MigrationDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ contract L2MigrationDeployer {
/// @dev Transfer failed
error TRANSFER_FAILED();

/// @dev Metadata call failed
error METADATA_CALL_FAILED();

/// ///
/// IMMUTABLES ///
/// ///
Expand Down Expand Up @@ -124,39 +127,29 @@ contract L2MigrationDeployer {
return (_token);
}

///@notice Adds metadata properties to the migrated DAO
/// @param _names The names of the properties to add
/// @param _items The items to add to each property
/// @param _ipfsGroup The IPFS base URI and extension
function addProperties(
string[] calldata _names,
IPropertyIPFSMetadataRenderer.ItemParam[] calldata _items,
IPropertyIPFSMetadataRenderer.IPFSGroup calldata _ipfsGroup
) external onlyCrossDomainMessenger {
(, address metadata, , , ) = _getDAOAddressesFromSender();
IPropertyIPFSMetadataRenderer(metadata).addProperties(_names, _items, _ipfsGroup);
}

///@notice Called once all metadata properties are added to set ownership of migrated DAO contracts to treasury
function finalize() external onlyCrossDomainMessenger {
(address token, , address auction, address treasury, ) = _getDAOAddressesFromSender();

// Transfer ownership of token contract
Ownable(token).transferOwnership(treasury);

// Transfer ownership of auction contract
Ownable(auction).transferOwnership(treasury);
}

///@notice Resets the stored deployment if L1 DAO wants to redeploy
function resetDeployment() external onlyCrossDomainMessenger {
_resetTokenDeployer();
}

/// ///
/// DEPOSIT ///
/// HELPER FUNCTIONS ///
/// ///

///@notice Helper method to pass a call along to the deployed metadata renderer
/// @param _data The names of the properties to add
function callMetadataRenderer(bytes memory _data) external onlyCrossDomainMessenger {
(, address metadata, , , ) = _getDAOAddressesFromSender();

// Call the metadata renderer
(bool success, ) = metadata.call(_data);

// Revert if metadata call fails
if (!success) {
revert METADATA_CALL_FAILED();
}
}

///@notice Helper method to deposit ether from L1 DAO treasury to L2 DAO treasury
function depositToTreasury() external payable onlyCrossDomainMessenger {
(, , , address treasury, ) = _getDAOAddressesFromSender();
Expand All @@ -170,6 +163,17 @@ contract L2MigrationDeployer {
}
}

///@notice Transfers ownership of migrated DAO contracts to treasury
function renounceOwnership() external onlyCrossDomainMessenger {
(address token, , address auction, address treasury, ) = _getDAOAddressesFromSender();

// Transfer ownership of token contract
Ownable(token).transferOwnership(treasury);

// Transfer ownership of auction contract
Ownable(auction).transferOwnership(treasury);
}

/// ///
/// PRIVATE ///
/// ///
Expand Down
3 changes: 3 additions & 0 deletions src/manager/IManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ interface IManager is IUUPS, IOwnable {
/// @dev Reverts if caller is not the token owner
error ONLY_TOKEN_OWNER();

/// @dev Reverts if caller is not the token owner
error INVALID_REWARDS_CONFIG();

/// ///
/// STRUCTS ///
/// ///
Expand Down
15 changes: 14 additions & 1 deletion src/manager/Manager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ import { IVersionedContract } from "../lib/interfaces/IVersionedContract.sol";
/// @custom:repo github.com/ourzora/nouns-protocol
/// @notice The DAO deployer and upgrade manager
contract Manager is IManager, VersionedContract, UUPS, Ownable, ManagerStorageV1, ManagerStorageV2 {
/// ///
/// CONSTANTS ///
/// ///

/// @notice The maximum combined BPS for referral and builder rewards
uint256 private constant MAX_REWARDS_BPS = 2_000;

/// ///
/// IMMUTABLES ///
/// ///
Expand Down Expand Up @@ -243,9 +250,15 @@ contract Manager is IManager, VersionedContract, UUPS, Ownable, ManagerStorageV1
emit UpgradeRemoved(_baseImpl, _upgradeImpl);
}

/// @notice Function to set the reward percentages
/// @notice Set the global reward configuration
/// @param _rewards The reward to be paid to the referrer in BPS
function setRewardConfig(RewardConfig calldata _rewards) external onlyOwner {
// Ensure the rewards are valid
if (_rewards.referralBps + _rewards.builderBps > MAX_REWARDS_BPS) {
revert INVALID_REWARDS_CONFIG();
}

// Set the rewards
rewards = _rewards;
}

Expand Down
9 changes: 5 additions & 4 deletions test/L2MigrationDeployer.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ contract L2MigrationDeployerTest is NounsBuilderTest {

addMetadataProperties();

deployer.finalize();
deployer.renounceOwnership();

vm.stopPrank();

Expand Down Expand Up @@ -90,7 +90,8 @@ contract L2MigrationDeployerTest is NounsBuilderTest {

MetadataRendererTypesV1.IPFSGroup memory ipfsGroup = MetadataRendererTypesV1.IPFSGroup({ baseUri: "BASE_URI", extension: "EXTENSION" });

deployer.addProperties(names, items, ipfsGroup);
bytes memory data = abi.encodeWithSignature("addProperties(string[],(uint256,string,bool)[],(string,string))", names, items, ipfsGroup);
deployer.callMetadataRenderer(data);
}

function setMinterParams() internal {
Expand Down Expand Up @@ -182,7 +183,7 @@ contract L2MigrationDeployerTest is NounsBuilderTest {
addMetadataProperties();

vm.expectRevert(abi.encodeWithSignature("NOT_CROSS_DOMAIN_MESSENGER()"));
deployer.finalize();
deployer.renounceOwnership();

vm.expectRevert(abi.encodeWithSignature("NOT_CROSS_DOMAIN_MESSENGER()"));
deployer.resetDeployment();
Expand All @@ -195,7 +196,7 @@ contract L2MigrationDeployerTest is NounsBuilderTest {
addMetadataProperties();

vm.expectRevert(abi.encodeWithSignature("NO_DAO_DEPLOYED()"));
deployer.finalize();
deployer.renounceOwnership();

vm.stopPrank();
}
Expand Down

0 comments on commit 11028af

Please sign in to comment.