The initVault function is meant to be called once at the launch of the protocol. However, it can be called as many times as wanted. To fix, create a way to limit the function to only being called once per airdrop and staking vault. Or use OpenZepplein's Initializable.sol. To fix, add boolean state variables originally set to false for both the airdrop and vault contracts. Have these bools set to true once they are called.
/// @notice Called at the launch of the protocol.
/// @notice Will distribute all the supply to Airdrop and Staking Contract.
function initVault(address managerContract) public {
if (msg.sender == airdropVault) {
_mint(airdropVault, 500_000_000 ether);
approve(managerContract, 500_000_000 ether);
emit AirdropInitialized(managerContract);
} else if (msg.sender == stakingVault) {
_mint(stakingVault, 500_000_000 ether);
approve(managerContract, 500_000_000 ether);
emit StakingInitialized(managerContract);
} else revert LoveToken__Unauthorized();
}
Nothing prevents this function from being called multiple times accept for the goodwill of the airdropVault and the stakingVault.
The initVault() function can be called multiple times to inflate the balance of either the airdropVault or the stakingVault.
function testMultipleinitVault() public {
soulmate = new Soulmate();
loveToken = new LoveToken(ISoulmate(address(soulmate)), address(this), address(this));
assertEq(0, loveToken.balanceOf(address(this)));
loveToken.initVault(address(this));
assertEq(500_000_000 ether, loveToken.balanceOf(address(this)));
loveToken.initVault(address(this));
assertEq(1_000_000_000 ether, loveToken.balanceOf(address(this)));
loveToken.initVault(address(this));
assertEq(1_500_000_000 ether, loveToken.balanceOf(address(this)));
}
Foundry
/// @notice Called at the launch of the protocol.
/// @notice Will distribute all the supply to Airdrop and Staking Contract.
function initVault(address managerContract) public {
if (msg.sender == airdropVault) {
require(wasAirdropVaultInit == false, "Airdrop Vault Already Initialized");
_mint(airdropVault, 500_000_000 ether);
approve(managerContract, 500_000_000 ether);
emit AirdropInitialized(managerContract);
wasAirdropVaultInit = true;
} else if (msg.sender == stakingVault) {
require(wasStakingVaultInit == false, "Staking Vault Already Initialized");
_mint(stakingVault, 500_000_000 ether);
approve(managerContract, 500_000_000 ether);
emit StakingInitialized(managerContract);
wasStakingVaultInit = true;
} else revert LoveToken__Unauthorized();
}
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.