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

fix(audit review) #38

Merged
merged 2 commits into from
May 11, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
13 changes: 1 addition & 12 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,4 @@ SemaphoreAirdropTest:testCannotClaimWithInvalidProof() (gas: 8797746687696282396
SemaphoreAirdropTest:testCannotClaimWithInvalidSignal() (gas: 2948678)
SemaphoreAirdropTest:testCannotDoubleClaim() (gas: 3004607)
SemaphoreAirdropTest:testCannotUpdateAirdropAmountIfNotManager() (gas: 16865)
SemaphoreAirdropTest:testUpdateAirdropAmount() (gas: 19308)
SemaphoreMultiAirdropTest:testCanClaim() (gas: 3122714)
SemaphoreMultiAirdropTest:testCanClaimAfterNewMemberAdded() (gas: 3789635)
SemaphoreMultiAirdropTest:testCanCreateAirdrop() (gas: 141458)
SemaphoreMultiAirdropTest:testCanUpdateAirdropDetails() (gas: 149676)
SemaphoreMultiAirdropTest:testCannotClaimHoursAfterNewMemberAdded() (gas: 3513319)
SemaphoreMultiAirdropTest:testCannotClaimIfNotMember() (gas: 3067076)
SemaphoreMultiAirdropTest:testCannotClaimNonExistantAirdrop() (gas: 2731400)
SemaphoreMultiAirdropTest:testCannotClaimWithInvalidProof() (gas: 8797746687696288053)
SemaphoreMultiAirdropTest:testCannotClaimWithInvalidSignal() (gas: 3069668)
SemaphoreMultiAirdropTest:testCannotDoubleClaim() (gas: 3125373)
SemaphoreMultiAirdropTest:testNonOwnerCannotUpdateAirdropDetails() (gas: 143499)
SemaphoreAirdropTest:testUpdateAirdropAmount() (gas: 19308)
4 changes: 0 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,8 @@ snapshot:; FOUNDRY_PROFILE=bench forge snapshot
# Deploy contracts
deploy-airdrop: install build; node --no-warnings scripts/deploy.js deploy-airdrop

deploy-multi-airdrop: install build; node --no-warnings scripts/deploy.js deploy-multi-airdrop

mock-airdrop: install build; node --no-warnings scripts/deploy.js mock-airdrop

mock-multi-airdrop: install build; node --no-warnings scripts/deploy.js mock-multi-airdrop

# ===== Utility Rules =================================================================================================

# Format the solidity code.
Expand Down
5 changes: 1 addition & 4 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,7 @@ optimizer_runs = 20000
verbosity = 3

# We can specify the contracts to track gas data for by tracing.
gas_reports = [
"WolrdIDAirdrop",
"WorldIDMultiAirdrop",
]
gas_reports = ["WolrdIDAirdrop"]

# === Production Profile ======================================================

Expand Down
40 changes: 0 additions & 40 deletions scripts/WorldIDMultiAirdrop.s.sol

This file was deleted.

93 changes: 0 additions & 93 deletions scripts/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,75 +236,6 @@ async function deployMockAirdrop(config) {
}
}

async function deployMockMultiAirdrop(config) {
dotenv.config();

await getPrivateKey(config);
await getEthereumRpcUrl(config);
await getEtherscanApiKey(config);
await deployWorldIDIdentityManagerRouterMock(config);
await getWorldIDIdentityManagerRouterAddress(config);
await saveConfiguration(config);
await getAirdropParameters(config);

const spinner = ora(`Deploying WorldIDAirdrop contract...`).start();

try {
const data = execSync(
`forge script scripts/WorldIDMultiAirdrop.s.sol:DeployWorldIDMultiAirdrop --fork-url ${config.ethereumRpcUrl} \
--etherscan-api-key ${config.ethereumEtherscanApiKey} --broadcast -vvvv`
);
console.log(data.toString());
spinner.succeed('Deployed WorldIDMultiAirdrop contract successfully!');
} catch (err) {
console.error(err);
spinner.fail('Deployment of WorldIDMultiAirdrop has failed.');
}
}

// TODO: Couldn't get it to work :(
// You can use the following instead
// To deploy Multi Airdrop:
// ```
// forge create --private-key $PRIVATE_KEY --rpc-url $RPC_URL src/WorldIDMultiAirdrop.sol:WorldIDMultiAirdrop --constructor-args $ADDRESS_OF_WORLD_ID_ROUTER
// ```
//
// To encode args for verification:
// ```
// cast abi-encode 'constructor(address)' $ADDRESS_OF_WORLD_ID_ROUTER
// ```
//
// To verify:
//
// ```
// forge verify-contract $ADDRESS_OF_MULTI_AIRDROP src/WorldIDMultiAirdrop.sol:WorldIDMultiAirdrop --etherscan-api-key $API_KEY --constructor-args $CONSTRUCTOR_ARGS_FROM_CAST_ENCODE --chain 137
// ```
async function deployMultiAirdrop(config) {
dotenv.config();

await getPrivateKey(config);
await getEthereumRpcUrl(config);
await getEtherscanApiKey(config);
await getWorldIDIdentityManagerRouterAddress(config);
await saveConfiguration(config);
await getAirdropParameters(config);

const spinner = ora(`Deploying WorldIDAirdrop contract...`).start();

try {
console.log('x');
const data = execSync(
`forge script scripts/WorldIDMultiAirdrop.s.sol:DeployWorldIDMultiAirdrop --legacy --fork-url ${config.ethereumRpcUrl} --broadcast -vvvv`
);
console.log('x');
console.log(data.toString());
spinner.succeed('Deployed WorldIDMultiAirdrop contract successfully!');
} catch (err) {
console.error(err);
spinner.fail('Deployment of WorldIDMultiAirdrop has failed.');
}
}

async function setAllowance(config) {
await getErc20Address(config);
await getHolderAddress(config);
Expand Down Expand Up @@ -342,17 +273,6 @@ async function main() {
await saveConfiguration(config);
});

program
.name('deploy-multi-aidrop')
.command('deploy-multi-airdrop')
.description('Interactively deploys the WorldIDMultiAirdrop contracts on Ethereum mainnet.')
.action(async () => {
const options = program.opts();
let config = await loadConfiguration(options.config);
await deployMultiAirdrop(config);
await saveConfiguration(config);
});

program
.name('mock-airdrop')
.command('mock-airdrop')
Expand All @@ -366,19 +286,6 @@ async function main() {
await saveConfiguration(config);
});

program
.name('mock-multi-airdrop')
.command('mock-multi-airdrop')
.description(
'Interactively deploys WorldIDIdentityManagerMock alongside with WorldIDMultiAirdrop for testing.'
)
.action(async () => {
const options = program.opts();
let config = await loadConfiguration(options.config);
await deployMockMultiAirdrop(config);
await saveConfiguration(config);
});

program
.name('set-allowance')
.command('set-allowance')
Expand Down
2 changes: 2 additions & 0 deletions src/WorldIDAirdrop.sol
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ contract WorldIDAirdrop {
nullifierHashes[nullifierHash] = true;

SafeTransferLib.safeTransferFrom(token, holder, receiver, airdropAmount);

emit AirdropClaimed(receiver);
}

///////////////////////////////////////////////////////////////////////////////
Expand Down
161 changes: 0 additions & 161 deletions src/WorldIDMultiAirdrop.sol

This file was deleted.

11 changes: 8 additions & 3 deletions src/test/WorldIDAirdrop.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {WorldIDAirdrop} from "../WorldIDAirdrop.sol";
/// functionality for a single airdrop.
contract WorldIDAirdropTest is PRBTest {
event AmountUpdated(uint256 amount);
event AirdropClaimed(address receiver);

address public user;
uint256 internal groupId;
Expand Down Expand Up @@ -56,14 +57,18 @@ contract WorldIDAirdropTest is PRBTest {
}

/// @notice Tests that the user is able to claim tokens if the World ID proof is valid
function testCanClaim(uint256 worldIDRoot, uint256 nullifierHash) public {
function testCanClaim(uint256 worldIDRoot, uint256 nullifierHash, address receiver) public {
vm.assume(worldIDRoot != 0 && nullifierHash != 0);

assertEq(token.balanceOf(address(this)), 0);

airdrop.claim(address(this), worldIDRoot, nullifierHash, proof);
vm.expectEmit(true, true, true, true);
emit AirdropClaimed(receiver);

assertEq(token.balanceOf(address(this)), airdrop.airdropAmount());
vm.prank(receiver);
airdrop.claim(receiver, worldIDRoot, nullifierHash, proof);

assertEq(token.balanceOf(receiver), airdrop.airdropAmount());
}

/// @notice Tests that nullifier hash for the same action cannot be consumed twice
Expand Down
Loading