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

victortzy_airdrop #17

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open

victortzy_airdrop #17

wants to merge 6 commits into from

Conversation

0xCheeezzyyyy
Copy link

First draft of the distributor contract. Note I purposely on restricted the registration rights to the owner but not the claim functions for possible future integration of external contracts.

Comment on lines 54 to 59
constructor(address[] memory accounts_, uint256[] memory shares_) payable {
require(accounts_.length == shares_.length, "Distributor: Mismatch of addresses and shares.");
for(uint256 i = 0; i < accounts_.length; i++ ){
_registerPayeesForETH(accounts_[i], shares_[i]);
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you only distribute shares for eth in the constructor =)))
You can do the same thing with erc20, assign in the constructor, or just do both outside the constructor.
this is weird to me since it is not consistent

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha yeah it may be abit weird, but my primary consideration was to only allow the owner to register payees with their respective shares once for each ERC20 token, starting with the native token ETH as the constructor so yeah. I could add in features to allow amendments to shares and addition of payees too

Comment on lines 81 to 86
require(address(this).balance >= ethClaimable, "Distributor: Insufficient ETH balance in contract.");

_totalETHDistributed += ethClaimable;
_distributedETH[account] = ethClaimable;
(bool success,) = account.call{value: ethClaimable}("");
require(success, "Distributor: Unable to receive ETH from contract.");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider using address.send(value) to limit gas in case the fallback account is malicious.
or you can use transfer to auto-revert if unsuccessfully transfer

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup okay thanks for the suggestion, sounds good 👍

Comment on lines 109 to 117
function distributeDemAllETH() external onlyOwner {
uint totalPayees = numRegisteredForETH();
for(uint256 i = 0; i < totalPayees;){
if(_sharesForETH[_payeesForETH[i]] > 0) {
payoutETH(payable(_payeesForETH[i]));
}
unchecked {i++; }
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will not revert if there is a payee does not have ETH allocated, unlike your below function for distributeDemAllToken will revert if this happens => inconsistent

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes sorry I overlooked this part, I could remove that line of code too because totalPayee refers to the actual number of accounts registered with shares for ETH, will amend it accordingly thanks!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be that they will not able to claim exactly amount they want ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They will be able to claim the proportion of funds deposited inside the contract based on their shares relative to the total shares, regardless of how many times it is being topped up

Comment on lines 120 to 127
function distributeDemAllToken(IERC20 token_) external onlyOwner {
IERC20 token = token_;
uint totalPayees = numRegisteredForToken(token);
for(uint256 i = 0; i < totalPayees;){
payoutToken(_payeesForToken[token][i], token);
unchecked {i++; }
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will revert if the share of one payee is 0

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It won't, because I am using a nested mapping to keep track of accounts registered under a particular token (means every account looped through will have shares > 0 for that token) itself

Comment on lines 138 to 140
require(account != address(0), "Distributor: Null address not allowed.");
require(share > 0, "Distributor: Invalid shares specified.");
require(_sharesForETH[account_] == 0, "Distributor: Account registered for ETH distribution.");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicated require statement, consider to declare modifiers

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah thanks alot, refracted both line 138 and 139 as modifiers!

Comment on lines 135 to 148
function _registerPayeesForETH(address account_, uint256 share_) private {
address account = account_;
uint share = share_;
require(account != address(0), "Distributor: Null address not allowed.");
require(share > 0, "Distributor: Invalid shares specified.");
require(_sharesForETH[account_] == 0, "Distributor: Account registered for ETH distribution.");

// Save account as a payee in the mapping
_payeesForETH[_numRegisteredForETH++] = account_;
_sharesForETH[account_] = share_;
_totalETHShares += share_;

emit RegisterPayeeForETH(account, share);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you update a share?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, I thought of implementing that at first but then I felt maybe it would be better if the proportion of shares were fixed when launched to preserve perpetuity of relative shares for each payee. Yeah, it would be bad if someone made a mistake in the shares breakdown and there would be many who would prefer to have it amendable also. So yeah I just didn't implement it first haha but its needed do I will gladly do it 👍

@0xCheeezzyyyy 0xCheeezzyyyy changed the title first commit victortzy_airdrop Jun 16, 2022
constructor(address[] memory accounts_, uint256[] memory shares_) payable {
require(accounts_.length == shares_.length, "Distributor: Mismatch of addresses and shares.");
for(uint256 i = 0; i < accounts_.length; i++ ){
_registerPayeesForETH(accounts_[i], shares_[i]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think not exposing this function to public makes it that if the owner want to airdrop for some users in the future, he won't be able to

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hence, strongly recommend to move it out of the constructor & expose it to be a public/external function

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah actually should make it flexible. Thanks a lot and will make the necessary amends!


// @Desc: To batch register accounts with a specified share for a new ERC20 Token
function registerPayeesForToken(address[] memory accounts_, IERC20 token_, uint256[] memory shares_) external onlyOwner {
require(accounts_.length == shares_.length, "Distributor: Mismatch of addresses and shares.");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good error message, I like it!

/*///////////////////////////////////////////////////////////////
Pure/View Functions
//////////////////////////////////////////////////////////////*/
function numRegisteredForETH() public view returns(uint256){
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for you to make the variable private & write public functions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants