{"id":49416962,"url":"https://github.com/singularity0x00/ethernaut_exploits","last_synced_at":"2026-04-29T03:11:42.327Z","repository":{"id":241040729,"uuid":"799207583","full_name":"Singularity0x00/ethernaut_exploits","owner":"Singularity0x00","description":"Solving ethernaut challenges","archived":false,"fork":false,"pushed_at":"2024-07-04T20:44:40.000Z","size":137,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-12T17:25:07.276Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Singularity0x00.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-05-11T13:10:28.000Z","updated_at":"2024-07-04T20:44:43.000Z","dependencies_parsed_at":"2025-04-12T17:25:10.963Z","dependency_job_id":"2f184fb8-a61d-4fa3-9302-09f405fb679c","html_url":"https://github.com/Singularity0x00/ethernaut_exploits","commit_stats":null,"previous_names":["hrideshg88/ethernaut_exploits","singularity0x00/ethernaut_exploits"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Singularity0x00/ethernaut_exploits","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Singularity0x00%2Fethernaut_exploits","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Singularity0x00%2Fethernaut_exploits/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Singularity0x00%2Fethernaut_exploits/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Singularity0x00%2Fethernaut_exploits/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Singularity0x00","download_url":"https://codeload.github.com/Singularity0x00/ethernaut_exploits/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Singularity0x00%2Fethernaut_exploits/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32408572,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T02:37:21.628Z","status":"ssl_error","status_checked_at":"2026-04-29T02:36:50.947Z","response_time":110,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-29T03:11:25.998Z","updated_at":"2026-04-29T03:11:42.319Z","avatar_url":"https://github.com/Singularity0x00.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EXPLOIT CONTRACTS FOR ETHERNAUT\n# LEVEL 0 hello_ethernaut\n\n\nplayer\n\"0x3A22d5B698CCb49b51B7B4D953a8Abb8F8a562cE\"\n\n\n\n# LEVEL 1 fallback\n\n\nplayer\n\"0x3A22d5B698CCb49b51B7B4D953a8Abb8F8a562cE\"\n\n\n\nOwner Address\n0x3c34A342b2aF5e885FcaA3800dB5B205fEfa3ffB\n\nSend eth without data to hit `recieve` and bypass `contribute() require(msg.value \u003c 0.001 ether);`\n\n# LEVEL 2 fallout\n\n\n\n\nSend eth to fal1out function and become owner.\nsollidity 0.6 constructor is declared by giving it same name as contract.\nbut fallout != fal1out\nso fal1out is public payable and has no onlyowner + owner = msg.sender.\n\n# LEVEL 3 coin_flip\n\n\n\n\ncopy function to exploit contract if true call coin_flip contract.\nrepeat till 10 consecutive wins.\n\n# LEVEL 4 telephone\n\n\n\n\ncreate a contract which calls changeowner on this contract.\nprofit!!!\n\n# LEVEL 5 token\n\n\n\n\nsimple overflow.\n\n# LEVEL 6 delegation\n\n\n\n\ndelegate call missuse exploiting context. send 0xdd365b8b via low lvl transaction with your own acc.\n\n# LEVEL 7 force\n\n\n\n\nselfdestruct and boom!!!\n\n# LEVEL 8 vault\n\n\n\n\n```\nweb3.eth.getStorageAt(addr, 1, console.log)\n\u003e null 0x412076657279207374726f6e67207365637265742070617373776f7264203a29\n\nweb3.utils.toAscii(\"0x412076657279207374726f6e67207365637265742070617373776f7264203a29\")\n'A very strong secret password :)'\n```\n\n# LEVEL 9 king\n\n\n\n\nexploit contract becomes king but has no recieve or fallback function breaking the recieve function in king contract\n\n# LEVEL 10 reentrancy\n\n\n\n\nStraightforward reentrancy attack.\n\n# LEVEL 11 elevator\n\n\n\n\nsend false when function is first called and true when it is called again.\n\n# LEVEL 12 privacy\n\n\n\n\n```\n// get the entry of data array at index 2.\nawait web3.eth.getStorageAt(contract.address, 5, console.log)\n\"0x14690fdf857625e4fe6f798d6ad3c7dbf82a6b1a6c9c082c0c6cfca4d394c4b1\"\n\n// convert 32 bytes to 16. (strip the last 16 bytes) and get the key\n\n0x14690fdf857625e4fe6f798d6ad3c7db\n```\n\n# LEVEL 13 gatekeeperone\n\n\n### Gateone\n\nbasically telephone challenge.\n\n### Gatetwo\n\n\u003e gasleft() % 8191 == 0; ????????\n\nBruteForce gas to send in local foundry env.\n\n### Gatethree\n\n```sol\nrequire(uint32(uint64(_gateKey)) == uint16(uint160(tx.origin)), \"GatekeeperOne: invalid gateThree part three\");\n```\n\nmeans last 4 characters of player address `0x62cE`\n\n```sol\nrequire(uint32(uint64(_gateKey)) == uint16(uint64(_gateKey)), \"GatekeeperOne: invalid gateThree part one\");\n```\n\nmeans zeroes before last 4 characters of key. `0x000062cE`\n\n```sol\nrequire(uint32(uint64(_gateKey)) != uint64(_gateKey), \"GatekeeperOne: invalid gateThree part two\");\n```\n\nmeans random non-zero 8 characters for the rest ??? `0x53a8abb8000062ce`\n\n# LEVEL 14 gatekeepertwo\n\n\n\n\nWhile constructor is running for a contract `EXTCODESIZE` for it's address will return 0.\n\n### SIMPLE THING TO REMEMBER:\n\n\u003e msg.sender == address of exploit contract for target. xD\n\n# LEVEL 15 naught_coin\n\n\n\n\n1. From main acc approve acc2 to be able to withdraw all tokens.\n2. Use allowance function to verify approval.\n3. From acc2 use transfer from function to withdraw all tokens.\n\n# LEVEL 16 preservation\n\n\n\n\nUnsafe delegate call use where it is possible to override variables of the contract. Once we can control the address of the contract it delegates to we can run our own code inside the contract. \u003cbr\u003e **Smart contract version of RCE **.\n\n# LEVEL 17 recovery\n\n\n\n\naddress for new contract in solidity by create opcode is computed by kecchak256(relp(sender, nonce))\nSender would be instance address(0xe473eF11db6be3F1bA29F3b8bc5B4e33D75E634f)\n\nso using the sender we can generate possible addresses and find the lost address.\nOnce found just call self destruct to recover all eth inside contract.\n\n# LEVEL 18 magic_number\n\n\n\n\nlow level\n\n# LEVEL 19 alien_codex\n\n\n\n\ncause the Codex[] to underflow using retract function. then overwrite the owner state variable using revise function.\n\n# LEVEL 20 denial\n\n\n\n\nset receive function such that it consumes all gas.\n\n# LEVEL 21 shop\n\n\n\n\nJust like the elevator but view functions cannot modify state variables hence gotta improvise and use conditionals to pass the if() check in buy function.\n\n# LEVEL 22 dex\n\n\n\n\n## TEST1\n\nspender - dexinstance\n| mytokens (start) | 1 swap usd-\u003einr | 2 swap | 3 swap |\n| ----------------- | ---------------- | -------- | ------ |\n| usd - 10 | 9 | 8 | 7 |\n| inr - 10 | 11 | 11 | 11 |\n| dextokens(start) | ---------------- | -------- | ------ |\n| ----------------- | ---------------- | -------- | ------ |\n| usd - 100 | 101 | 102 | 103 |\n| inr - 100 | 99 | 99 | 99 |\n\nswap price (1 swap usd-\u003einr)-\u003e(2 swap)-\u003e(3 swap)\n1 token -\u003e 0 -\u003e 0 -\u003e 0\n100 token -\u003e 98 -\u003e 97 -\u003e 96\nswap ammount 0 hence inr not increasing in above table.\n\nswap price (1 swap inr-\u003eusd)-\u003e(2 swap)-\u003e(3 swap)\n1 token -\u003e _ -\u003e _-\u003e 1\n100 token -\u003e _ -\u003e _-\u003e 104\n\n!('./dexbrainstorming.png')\n\nINCREASE THE `swap amount` TO DRAIN THE DEX CONTRACT.\n\nso basically swap from token1 to token2 and then swap from token2 to token1 and vice versa, until you can empty tokens from dex contract.\n\n# LEVEL 23 dextwo\n\n\n\n\nCan I deploy my own tokens??? yeah.\nCreate Fake tokens and give dex2 just 10 so that 10 of fake 100 of dex2's.\n\n# LEVEL 24 puzzlewallet\n\n\ntransparent upgradeable proxy.(upgrade and admin logic handled by proxy itself)\n\n\u003e address(uint160(maxbalance)) == admin address....... wtf..\n\ncan make proxy balance zero by delegating call to `execute`. provided player and wallet contract have enough balance\n\n- step 1: call `proposeNewAdmin(address)`and become pending admin.\n- step 2: call `addToWhitelist(address)` and become Whitelisted.\n- step 3: use multicall with \\[\"deposit\",\"multicall(deposit)\"] as parameter to rick contract into calling deposit twice\n- step 4: call execute to empty the balance.\n- step 5: call set maxBalance to becom admin.\n\n\u003e proxy's fallback function delegates call to implementation and there is a collision in state variables which can be exploited to cause chaos\n\n\n# LEVEL 25 motorbike\n\n\n\n\n## PRE DECUN SOLUTION\n\nGet the implementation address.\n\n```javascript\nawait web3.eth.getStorageAt(\n  contract.address,\n  \"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\",\n);\n```\n\ninitialize the implementation to become upgrader then call `upgradeToAndCall()` func with exploit contract addr and selfdestruct func identifier.\n\n## AFTER DECUN UPDATE (courtesy of https://github.com/Ching367436)\n\nThe selfdestruct function will no longer remove the contract code after the upgrade, so the above solution will not work.\n\nso we would need to use a contract to call ethernaut contract to create an instance and the in the same transaction perform the above exploit to solve the challenge. but still won't appear on the ethernaut client side. \u003cbr\u003e\nmy solution txn:\u003cbr\u003e\nhttps://sepolia.etherscan.io/tx/0x05599a912ee760312d6a5585762887b4bc499022b100cd31c73867bb7d9666ab\n\n# LEVEL 26 doubleentrypoint\n\n\n\nLegacyToken can delegate to new contract so if legacy token delegates to DET, DET can be swept from vault.\nbot should monitor delegateToNewContract function of Legacytoken.\n\n# LEVEL 27 good_samaritan\n\n\n\n\nBackdoor function `notify` inside of coin contract can be leveraged to pass custom error value like `NotEnoughBalance()` which will make the good samaritan contract jump into `catch` statement and give us tokens.\n\n# LEVEL 28 gatekeeperthree\n\n\n\n\nStraightForwad.\nget password from trick's storage -\u003e put \u003e0.001 eth into gatekeeper-\u003e deploy a contract without fallback or recieve and call constructor for gatekeeper. enter.\n\n\u003e why did I not directly fund gatekeeper and used a hacky way instead?? realized later lol.\n\n# LEVEL 29 switch\n\n\n\n\n```sol\n assembly {\n            calldatacopy(selector, 68, 4) // grab function selector from calldata\n        }\n```\n\nCopies 4 bytes from the calldata from the 68th byte to write to memory at location `selector`. where,\n`selector` can only be `offSelector`\n\n**Copies 4 bytes from the calldata from the 68th byte** means we can control the calldata as long as `0x20606e15` is present at 68th byte of calldata.\n\n## Exploit calldata\n\n```javascript\nawait sendTransaction({\n  from: player,\n  to: contract.address,\n  data: \"0x30c13ade0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000020606e1500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000476227e1200000000000000000000000000000000000000000000000000000000\",\n});\n\nawait contract.switchOn(); // should return true\n```\n\n# LEVEL 30 higherorder\n\n\n\n\n```DOCS\n\u003e ### THINGS TO AVOID \u003cbr\u003e\n\u003e\n\u003e Inline assembly might have a quite high-level look, but it actually is extremely low-level. Function calls, loops, ifs and switches are converted by simple rewriting rules and after that, the only thing the assembler does for you is re-arranging functional-style opcodes, counting stack height for variable access and removing stack slots for assembly-local variables when the end of their block is reached.\n```\n\nWhile solidity does enforce type-checking **_EVM does not_**.\nBy sending a low level call to `registerTreasury(uint8)` function we can bypass the restriction of uint8 type as it is enforced by solidity and not by the EVM.\n\n\u003e ABI encoder v2 impliments type checking safegaurds for contracts compiled with sol v0.8.0 onwards\n\n# LEVEL 31 stake\n\n\n\n\n`0xdd62ed3e , 0x23b872dd` are vuln to collisions.\u003cbr\u003e\n`0x23b872dd: transferFrom(address,address,uint256) `\u003cbr\u003e\n`0xdd62ed3e: allowance(address,address)` \u003cbr\u003e\ncontract does not handle false return for low level calls.\ncan stake weth without having any.\n\n- step 1: use another EOA to fund stake with 0.002 ether.\n- step 2: sendETH 8000000000000000 wei\n- step 3: send Weth \"2000000000000000\" weth\n- step 4: unstake 9900000000000000 such that contract eth = 0.0001\n- step 5: unstake remaining stake\n\nthis works because ` (bool success, ) = payable(msg.sender).call{value : amount}(\"\");` in function `Unstake(uint256)` will give you ether if contract has enough balance othwerwise it will pay in weth\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsingularity0x00%2Fethernaut_exploits","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsingularity0x00%2Fethernaut_exploits","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsingularity0x00%2Fethernaut_exploits/lists"}