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

Puppet Unsolvable in 1 Transaction #29

Closed
BlueAlder opened this issue Feb 2, 2023 · 4 comments
Closed

Puppet Unsolvable in 1 Transaction #29

BlueAlder opened this issue Feb 2, 2023 · 4 comments

Comments

@BlueAlder
Copy link

I am updating all my solutions to the new v3 implementation (nice job by the way!). I am making my way through and am stuck on the new requirement of the puppet problem. Specifically the requirement for the entire solution to be solved in 1 transaction.

https://github.com/tinchoabbate/damn-vulnerable-defi/blob/a5d47759c2132175ed8b5b42a6ba28c1e436032d/test/puppet/puppet.challenge.js#L103

I think this was introduced due to this PR.

I am not sure if I am just dumb and can't work it out but as far as I can tell, at least 2 transactions are required and if you use a contract to do this all for you then you will need to transfer tokens to the contract as well as create the contract.

@BlueAlder BlueAlder closed this as not planned Won't fix, can't repro, duplicate, stale Feb 5, 2023
@BlueAlder
Copy link
Author

Lol i'm just dumb never mind

@RealJohnnyTime
Copy link

How did you solve it in 1 tx?
I solved it like this:

it('Execution', async function () {
    /** CODE YOUR SOLUTION HERE */

    [,,this.player2] = await ethers.getSigners();


    const AttackerContractFactory = await ethers.getContractFactory('AttackPuppet', this.player2);
    this.attackerContract = await AttackerContractFactory.deploy(
        token.address, uniswapExchange.address, lendingPool.address
    )

    token.connect(player).transfer(this.attackerContract.address, PLAYER_INITIAL_TOKEN_BALANCE);
    await this.attackerContract.attack({value: 11n * 10n ** 18n});
    await token.connect(this.player2).transfer(player.address, await token.balanceOf(this.player2.address));

});

@BlueAlder
Copy link
Author

Yeah it's possible to solve in 1 transaction. You can handle all the logic required (including the transfers) in the deployment of the contract and that is the single transaction.

Spoiler warning If you just want to see the answer you can see my solution here. It uses `signERC2612Permit()` to allow the contract to transfer the tokens from the player contract

https://github.com/BlueAlder/damn-vulnerable-defi/blob/e90075150d9ba275197d15b62d07a2cbab9f8da1/test/puppet/puppet.challenge.js#L205

@RealJohnnyTime
Copy link

Didn't think about that! Cool! :)

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

No branches or pull requests

2 participants