Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update distributor #384

Merged
merged 4 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 10 additions & 18 deletions contracts/distribution/TokenDistributor.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.20;

import "openzeppelin/contracts/security/ReentrancyGuard.sol";
import "../globals/IGlobals.sol";
import "../globals/LibGlobals.sol";
import "../tokens/IERC20.sol";
Expand All @@ -12,7 +13,7 @@ import "../utils/LibSafeCast.sol";
import "./ITokenDistributor.sol";

/// @notice Creates token distributions for parties.
contract TokenDistributor is ITokenDistributor {
contract TokenDistributor is ITokenDistributor, ReentrancyGuard {
using LibAddress for address payable;
using LibERC20Compat for IERC20;
using LibRawResult for bytes;
Expand Down Expand Up @@ -105,7 +106,7 @@ contract TokenDistributor is ITokenDistributor {
Party party,
address payable feeRecipient,
uint16 feeBps
) external payable returns (DistributionInfo memory info) {
) external payable nonReentrant returns (DistributionInfo memory info) {
info = _createDistribution(
CreateDistributionArgs({
party: party,
Expand All @@ -124,7 +125,7 @@ contract TokenDistributor is ITokenDistributor {
Party party,
address payable feeRecipient,
uint16 feeBps
) external returns (DistributionInfo memory info) {
) external nonReentrant returns (DistributionInfo memory info) {
info = _createDistribution(
CreateDistributionArgs({
party: party,
Expand All @@ -141,7 +142,7 @@ contract TokenDistributor is ITokenDistributor {
function claim(
DistributionInfo calldata info,
uint256 partyTokenId
) public returns (uint128 amountClaimed) {
) public nonReentrant returns (uint128 amountClaimed) {
// Caller must own the party token.
{
address ownerOfPartyToken = info.party.ownerOf(partyTokenId);
Expand Down Expand Up @@ -185,7 +186,10 @@ contract TokenDistributor is ITokenDistributor {
}

/// @inheritdoc ITokenDistributor
function claimFee(DistributionInfo calldata info, address payable recipient) public {
function claimFee(
DistributionInfo calldata info,
address payable recipient
) public nonReentrant {
// DistributionInfo must be correct for this distribution ID.
DistributionState storage state = _distributionStates[info.party][info.distributionId];
if (state.distributionHash != _getDistributionHash(info)) {
Expand Down Expand Up @@ -364,25 +368,13 @@ contract TokenDistributor is ITokenDistributor {
uint256 amount
) private {
bytes32 balanceId = _getBalanceId(tokenType, token);
// Reduce stored token balance.
uint256 storedBalance = _storedBalances[balanceId] - amount;
// Temporarily set to max as a reentrancy guard. An interesing attack
// could occur if we didn't do this where an attacker could `claim()` and
// reenter upon transfer (e.g. in the `tokensToSend` hook of an ERC777) to
// `createERC20Distribution()`. Since the `balanceOf(address(this))`
// would not of been updated yet, the supply would be miscalculated and
// the attacker would create a distribution that essentially steals from
// the last distribution they were claiming from. Here, we prevent that
// by causing an arithmetic underflow with the supply calculation if
// this were to be attempted.
_storedBalances[balanceId] = type(uint256).max;
_storedBalances[balanceId] -= amount;
if (tokenType == TokenType.Native) {
recipient.transferEth(amount);
} else {
assert(tokenType == TokenType.Erc20);
IERC20(token).compatTransfer(recipient, amount);
}
_storedBalances[balanceId] = storedBalance;
}

function _getDistributionHash(
Expand Down
9 changes: 8 additions & 1 deletion contracts/renderers/PartyNFTRenderer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,10 @@ contract PartyNFTRenderer is RendererBase {
IMetadataRegistry1_1 constant OLD_METADATA_REGISTRY =
IMetadataRegistry1_1(0x175487875F0318EdbAB54BBA442fF53b36e96015);
/// @notice The old token distributor contract address.
/// @dev Cannot store immutable arrays...
address immutable TOKEN_DISTRIBUTOR_V1;
address immutable TOKEN_DISTRIBUTOR_V2;
address immutable TOKEN_DISTRIBUTOR_V3;

/// @notice The base url for external URLs. External URL is BASE_EXTERNAL_URL + PARTY_ADDRESS
/// @dev First byte is the size of the data, the rest is the data (starting from MSB)
Expand All @@ -89,11 +91,13 @@ contract PartyNFTRenderer is RendererBase {
IFont font,
address tokenDistributionV1,
address tokenDistributionV2,
address tokenDistributionV3,
string memory baseExternalURL
) RendererBase(globals, rendererStorage, font) {
IMPL = address(this);
TOKEN_DISTRIBUTOR_V1 = tokenDistributionV1;
TOKEN_DISTRIBUTOR_V2 = tokenDistributionV2;
TOKEN_DISTRIBUTOR_V3 = tokenDistributionV3;

bytes memory baseExternalURLBytes = bytes(baseExternalURL);
if (baseExternalURLBytes.length > 31) {
Expand Down Expand Up @@ -662,11 +666,14 @@ contract PartyNFTRenderer is RendererBase {
if (address(this) == IMPL) return false;

// There will only be one distributor if old token distributor is not set
TokenDistributor[] memory distributors = new TokenDistributor[](3);
TokenDistributor[] memory distributors = new TokenDistributor[](4);
distributors[0] = TokenDistributor(
_GLOBALS.getAddress(LibGlobals.GLOBAL_TOKEN_DISTRIBUTOR)
);
uint256 l = 1;
if (TOKEN_DISTRIBUTOR_V3 != address(0)) {
distributors[l++] = TokenDistributor(TOKEN_DISTRIBUTOR_V3);
}
if (TOKEN_DISTRIBUTOR_V2 != address(0)) {
distributors[l++] = TokenDistributor(TOKEN_DISTRIBUTOR_V2);
}
Expand Down
1 change: 1 addition & 0 deletions deploy/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ abstract contract Deploy {
IFont(address(pixeldroidConsoleFont)),
deployConstants.tokenDistributorV1,
deployConstants.tokenDistributorV2,
deployConstants.tokenDistributorV3,
deployConstants.baseExternalURL
);
_trackDeployerGasAfter();
Expand Down
11 changes: 11 additions & 0 deletions deploy/LibDeployConstants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ library LibDeployConstants {
uint96 contributionRouterInitialFee;
address tokenDistributorV1;
address tokenDistributorV2;
address tokenDistributorV3;
string baseExternalURL;
}

Expand Down Expand Up @@ -60,6 +61,7 @@ library LibDeployConstants {
contributionRouterInitialFee: 0.00055 ether,
tokenDistributorV1: 0x0000000000000000000000000000000000000000,
tokenDistributorV2: 0x0000000000000000000000000000000000000000,
tokenDistributorV3: 0x0000000000000000000000000000000000000000,
baseExternalURL: "https://party.app/party/"
});

Expand Down Expand Up @@ -94,6 +96,7 @@ library LibDeployConstants {
contributionRouterInitialFee: 0.00055 ether,
tokenDistributorV1: 0x0000000000000000000000000000000000000000,
tokenDistributorV2: 0x0000000000000000000000000000000000000000,
tokenDistributorV3: 0x0000000000000000000000000000000000000000,
baseExternalURL: "https://party.app/party/"
});

Expand Down Expand Up @@ -129,6 +132,7 @@ library LibDeployConstants {
contributionRouterInitialFee: 0.00055 ether,
tokenDistributorV1: 0xE6F58B31344404E3479d81fB8f9dD592feB37965,
tokenDistributorV2: 0x8714EA9C2BC5a8f2d26D7c3F86558331c16145B5,
tokenDistributorV3: 0x0000000000000000000000000000000000000000,
baseExternalURL: "https://party.app/party/"
});

Expand Down Expand Up @@ -164,6 +168,7 @@ library LibDeployConstants {
contributionRouterInitialFee: 0.00055 ether,
tokenDistributorV1: address(0),
tokenDistributorV2: 0x55D2463cf5b6743F279Fe9BcbF32415f575B953d,
tokenDistributorV3: 0x0000000000000000000000000000000000000000,
baseExternalURL: "https://base.party.app/party/"
});

Expand Down Expand Up @@ -199,6 +204,8 @@ library LibDeployConstants {
contributionRouterInitialFee: 0.00055 ether,
tokenDistributorV1: 0x1CA2007a81F8A7491BB6E11D8e357FD810896454,
tokenDistributorV2: 0x49a3caab781f711aD74C9d2F34c3cbD835d6A608,
// TODO: Add token distributor V3 address
tokenDistributorV3: 0x0000000000000000000000000000000000000000,
baseExternalURL: "https://party.app/party/"
});

Expand Down Expand Up @@ -234,6 +241,8 @@ library LibDeployConstants {
contributionRouterInitialFee: 0.00055 ether,
tokenDistributorV1: address(0),
tokenDistributorV2: 0xf0560F963538017CAA5081D96f839FE5D265acCB,
// TODO: Add token distributor V3 address
tokenDistributorV3: 0x0000000000000000000000000000000000000000,
baseExternalURL: "https://base.party.app/party/"
});

Expand Down Expand Up @@ -268,6 +277,8 @@ library LibDeployConstants {
contributionRouterInitialFee: 0.00055 ether,
tokenDistributorV1: address(0),
tokenDistributorV2: address(0),
// TODO: Add token distributor V3 address
tokenDistributorV3: 0x0000000000000000000000000000000000000000,
baseExternalURL: "https://zora.party.app/party/"
});

Expand Down
2 changes: 1 addition & 1 deletion lib/party-addresses
Submodule party-addresses updated 310 files
1 change: 1 addition & 0 deletions test/crowdfund/InitialETHCrowdfund.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ contract InitialETHCrowdfundTestBase is LintJSON, TestUtils, ERC721Receiver {
font,
address(0),
address(0),
address(0),
"https://party.app/party/"
);
tokenDistributor = new TokenDistributor(globals, 0);
Expand Down
1 change: 1 addition & 0 deletions test/party/PartyGovernanceNFT.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ contract PartyGovernanceNFTTestBase is LintJSON, TestUtils {
font,
address(0),
address(0),
address(0),
"https://party.app/party/"
);
globalsAdmin.setGovernanceNftRendererAddress(address(nftRenderer));
Expand Down
1 change: 1 addition & 0 deletions test/utils/PartyGovernanceHelpers.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ contract PartyGovernanceHelpersTest is Test, TestUtils {
IFont(address(0)),
address(0),
address(0),
address(0),
"https://party.app/party/"
);
globalsAdmin.setGovernanceNftRendererAddress(address(nftRenderer));
Expand Down
Loading