@taichiaudit Founder | Whitehat doing mediations @Immunefi | Core Member @DeFiHackLabs

GMT+8
Easter egg trigged
11 crit/high reports submitted to the same program, 3 dups, others waiting review🤣
6
30
1,341
Paid $250 bucks for a mediation and got closed after 25 minutes with this response, stay away from this scam. Do not pay for mediation.
8
1
90
5,822
Replying to @chrisdior777
Need to be a good lawyer to get beg bounty
1
6
104
Glad to join the @HackenProof Vanguard program! Will spend more time hunting bugs on HP and share knowledge with the community🫡
2
29
1,533
Replying to @brandon_shi
Immunefi triaged ones like this?
61
Replying to @blckhv

ALT Paul Bearer Dance GIF by Jason Clarke

1
3
228
Passed Daml fundamentals cert exam😁Thanks @digitalasset for the great intro course
2
23
1,711
Translation: you passed verification but we won't allow you to do your regular job, what you gonna do about it kid?
2
7
1,462
There is a second bug that makes this path reachable much more easily: the insolvency gate is broken. The comments say liquidation should depend on the borrower’s shortfall (the underwater amount), but calculateDiscountedRepayToEvenAmount() reads the target account’s shortfall and then never uses it. You can ctrl+f for accountShortfall_TargetUser and see it is not used anywhere in the contract. Instead, the close cap (the maximum amount of the borrower’s debt that this liquidation is allowed to repay in one call) is effectively derived from close factor and borrow balance.
1
1
180
During the write phase it stores the borrower-side result, then stores the liquidator-side result. Because both storage variables point to the same slot, the second write overwrites the first one. Net result: the slot ends up with a + b, not a neutral self-transfer. So the liquidation repays real debt but credits extra internal collateral to the attacker.
1
1
98
After that, the code first computes localResults.updatedSupplyBalance_TargetCollateralAsset = localResults.currentSupplyBalance_TargetCollateralAsset - localResults.seizeSupplyAmount_TargetCollateralAsset. It then computes localResults.updatedSupplyBalance_LiquidatorCollateralAsset = localResults.currentSupplyBalance_LiquidatorCollateralAsset + localResults.seizeSupplyAmount_TargetCollateralAsset. You can think of this as localResults.updatedSupplyBalance_TargetCollateralAsset = a - b and updatedSupplyBalance_LiquidatorCollateralAsset = a + b.
1
1
108
Then the function converts checkpointed storage balances into accumulated local balances. borrowBalance_TargeUnderwaterAsset becomes localResults.currentBorrowBalance_TargetUnderwaterAsset via calculateBalance(borrowBalance_TargeUnderwaterAsset.principal, borrowBalance_TargeUnderwaterAsset.interestIndex, localResults.newBorrowIndex_UnderwaterAsset). Likewise, supplyBalance_TargetCollateralAsset becomes localResults.currentSupplyBalance_TargetCollateralAsset, and supplyBalance_LiquidatorCollateralAsset becomes localResults.currentSupplyBalance_LiquidatorCollateralAsset, by calling calculateBalance() with each balance's stored principal, stored interestIndex, and the shared localResults.newSupplyIndex_CollateralAsset. Here you can see that localResults.currentSupplyBalance_TargetCollateralAsset and localResults.currentSupplyBalance_LiquidatorCollateralAsset will have the same value.
1
1
383
The exploitable case is targetAccount == msg.sender and assetBorrow == assetCollateral. Under that condition, supplyBalance_TargetCollateralAsset and supplyBalance_LiquidatorCollateralAsset are not two independent positions. They are two storage references to the exact same supplyBalances slot. So the function is effectively trying to transfer collateral from an account back to itself using two aliased pointers.
1
1
135
High level understanding first: Alkemi tracks user positions in internal balance records: - supplyBalances[account][asset] for supplied collateral - borrowBalances[account][asset] for debt Each record is just a checkpointed principal plus an interestIndex. When the protocol needs the live amount, it accrues interest into a local variable with calculateBalance(). That function just computes the formula below:
1
3
311
Molt EVM is hacked because of a trivial access control vuln. Code: vscode.blockscan.com/8453/0x… `onlySpawnerToken` modifier only checks: 1. caller is a contract 2. caller implements `initialized()` function that returns 32-byte of data and evaluates to true Anyone can deploy such contract easily and call `mintFromSpawner` for arbitrary mint. Attacker just minted for free and sold.
3
3
65
5,319
👍I am permanently away from PJQA on code4rena, thanks!
3
11
552
Glad to sponsor osu!gaming CTF! Come play
We are happy to host osu!gaming CTF 2025 (Rhythm Game Edition), happening next weekend. View the prizes and register at: osugaming.sekai.team @osugame is a fast-paced, precision-oriented rhythm game. Now, with osu!gaming CTF, we've brought the excitement to the world of CTFs.
26
2,583
Spent ~2 weeks on Solana confidential transfer zk contest, but didn't make it to the final leaderboard cause only top 3 qa reports get paid. A bit frustrating, but here is the evidence of me made it to top 7 at least😂
3
2
45
2,904
Received @rektoff_xyz bootcamp graduation cert today! Thanks Rektoff for the amazing lectures, exercises, and of course the capstone. The bootcamp was a fantastic introduction to the Rust/Solana security world🙏
3
1
41
1,946
CertiK strong🤯
2
28
6,732
Bye bye cursor, you do your sanction thing, I get refund, we both happy
2
14
1,856
The math gives an optimized swap amount as shown in the image. If you swap this much WBTC, then every ETH and every WBTC will be used when providing liquidity to ETH/WBTC pool, and you get max amount of LP tokens on behalf of user.
1
4
423
If a CTF chall is solvable, I will solve it given sufficient time, that's my promise. Solved magic of solidity on dreamhack, thanks @lj1nu for making this hard chall 🥶 Probably spent 30 hours on this one. GG
6
56
3,566
Only 0.4 away from winning🤣 Achievement so far: - RACE #37 1st place - RACE #42 2nd place - RACE #20 2nd place - RACE #27 3rd place I am from @TaiChiWeb3Sec
7
3
70
2,849
Thanks @rektoff_xyz ! The acceptance rate is crazy 🥶
4
66
5,684
Wow!
7
1
40
3,882
Replying to @0xSorryNotSorry

ALT Jojo Bizarre GIF

3
204
Right now we have 3 members from @DeFiHackLabs CTF team solved all challs on @onlypwner: @YQ996CO28254695 , @LHuangkun and myself😀 If you are a top player at onlyPwner and you want to play CTF with a team, please DM me! We are always looking for talented new members.
3
3
32
8,798
Replying to @eugenioclrc
>140k usd a year would make me happy as pigs in shit as well

ALT Peppa Pig Animation GIF

1
1
197
What about over finite field? This had bothered me a lot and fortunately I found it in Gallian's "Contemporary Abstract Algebra" chapter 16 today. Basically it says this theorem is not true for finite field in general but it is true when field modulus is prime.
4
5
576
But how do we know the numerator is bounded by d? There is a theorem saying poly of degree d has at most d distinct roots, but it is over a field, not finite field. For example you can find the theorem here: abstract.ups.edu/aata/poly-s…
1
4
220
It is easy to see that it is cyclic when curve_order is prime. The cyclicity is guaranteed by a corollary of Lagrange Theorem. A reference can be found here: abstract.ups.edu/abstract.up… Specifically I am talking about corollary 6.12:
1
64
I found this stackexchange answer: math.stackexchange.com/quest…, this theorem says there are only two cases for elliptic curve over finite field, it is either a cyclic group or a direct product of two cyclic groups.
1
2
89
To see an example of how transient storage works, I watched smart contract programmer's video: piped.video/0-hiB5I39Mk?si=0e6K… In this video he demonstrates a demo where you can see the effect of TSTORE gets reset at the end of tx. He also showed a real use case of reentrancy lock.
1
4
90
I finally recall my uniswap v3 mission today. First I started with Owen's video: piped.video/Ltph_X60kbo?si=4NDl… This video explains how uniswap v3 concentrated liquidity works from a high level. Mainly it discusses ticks, how to compute price, how liquidity provision works.
1
1
89
How to find that unique polynomial of order n based on given n+1 points? The algorithm is called "Lagrange Interpolation". I watched this video to understand it geometrically: piped.video/bzp_q7NDdd4?si=Xof-…
2
1
173
The second fact is "degree n polynomial has n zeros". I googled a bit and found it is just another way of stating Fundamental Theorem of Algebra: en.wikipedia.org/wiki/Fundam…
1
2
242
Received swag from @OpenZeppelin, thanks!
3
53
2,111
Replying to @74v15hq
Lol look at mine
1
1
33
Ranked 10th in @TheSecureum RACE 28. Not bad, but I just want to win a RACE😂So hard to win
1
31
1,361
Look at that rustonomicon logo... No wonder people say Rust is a cult😂 source: tourofrust.com/55_en.html
4
424
I been participating in @TheSecureum RACEs for about a year, here is what I achieved: - 6 times top 32 - 4 times top 10 - 3 times top 5 - Highest ranking was 2nd place Goal: win 1st place in the next couple of months.
2
28
1,628
I found an interesting question in Stanford CS251 2021 final exam: cs251.stanford.edu/hw/final2… Given the code below, 1) Suppose totalSupply() == 16370, what is the maximum number of NFTs that you can still mint? 2) Briefly write an attack contract 3) Mitigate by modifying one line
4
5
40
9,192
Fun fact: this is a merkle tree
1
4
216
@onlypwner Bridge Takeover solved 😎
1
5
203
After some research I came across this info on evm.codes:
1
3
215
Run `forge test -vvvv` and we see the message "logic after entry point" is executed each time this function gets re-entered. It shows that the logic after the entry point will be executed multiple times, just like the logic before the entry point.
1
104
My understanding was wrong. Let's modify the code a bit and test it in Foundry.
1
101
For example, consider this sample code from github.com/SunWeb3Sec/DeFiVu… The reentrancy entry point is the low-level call in the red box. I used to think that only the logic before the low-level is will be executed multiple times, and the logic after it will be executed only once.
1
118
In the screenshot, the `bytecode` variable should be the return value of getBytecode(). So beyond the actual bytecode of the target contract, you have to include the two input parameters as well. Here is the target contract implementation:
1
2
266
When reading this article on create2 by @ProgrammerSmart : solidity-by-example.org/app/…, I found a subtle detail that I did not realize: if the constructor contains input parameters, you should take that into account when computing the address:
1
3
25
3,191
In contrast, testAssemblyReturn() will immediately execute the return opcode, therefore _status = NOT_ENTERED; will never be executed:
1
137
Let's use Remix debugger to see the opcodes in action. In testSolidityReturn(), the value 0x42 is stored on the stack and _status = NOT_ENTERED; is executed before the final return:
1
1
170
Call testAssemblyReturn() and check the value of _status. The result is not looking good:
1
107
Call testSolidityReturn() and check the value of _status. The result is as expected:
1
133
@TheSecureum RACE #20 ( designed by @hrkrshnn ) question 5 taught me one thing: "return" in Solidity and "return" in Yul behave differently. I wrote a demo contract:
2
13
1,400
@0xAA_Science 书收到了 哥哥加油出全套
2
3
643
Congrats to @TheSecureum RACE 20 winners 🥳 @QiuhaoLi too OP need nerf
3
20
1,769
In conclusion, dynamic types are encoded as 3-part (offset+length+data) in calldata but 2-part (length+data) in memory. Static types don't have this complication. Which types are dynamic types you might ask? Check Solidity doc: docs.soliditylang.org/en/lat…
1
2
192
Note that "Tuple Encoded" is just a fancy way of saying calldata, because function arguments are encoded as a "tuple". Next, we test the behavior of fixed-length array and dynamic array. Here we can see that fixed-length array does not have offset pointer but dynamic array has.
1
2
174
The offset pointer is definitely needed, otherwise there is no way to know where the dynamic type argument starts. In contrast, this offset pointer is not needed in memory because data are stored consecutively in memory. In chisel, we can confirm this fact:
1
2
176
First, let's take a look at the ABI encoding for string in the calldata case. Here we can see that there is an offset pointer pointing to the beginning of the string's data. The second argument `uint256 1` is actually stored before the first argument "Hello".
1
2
170
Yesterday I saw a question asked in @opensensepw discord server. The Yul code basically just stores some string in memory. The question is why is it 3-part: 0x20 + length + ASCII. In particular, what does the 0x20 do.
3
3
20
2,548
Ranked 15th in @TheSecureum RACE 19. Aiming for top 3 next time!
3
12
989
In the next video, Smart Contract Programmer discussed the implementation of such gas-less token transfer contract: piped.video/jYNnatXRsBs There are 3 actors in this contract: - sender: Alice with 10 DAI - receiver: Bob with nothing - address(this): Carol with 1 ETH Recall that Alice wants to send 10 DAI to Bob and she has to pay Carol 1 DAI for the gas fee. The `send()` function will do the following things: 1. permit() - sender approves this contract to spend amount + fee 2. transferFrom(sender, receiver, amount) - Alice pays Bob 10 DAI 3. transferFrom(sender, msg.sender, fee) - Alice pays this contract 1 DAI for gas fee In step 1, the `permit()` function comes from OpenZeppelin ERC20Permit: docs.openzeppelin.com/contra…. This function allows approvals to be made via signatures, so the sender does not need to call `approve()`, which needs gas fee itself. I am aware of the signature being used here, and it is usually the source of vulnerabilities. I might write a dedicated article explaining various signature attacks. Stay tuned!
1
92
Continuing the gas-less token transfer discussion, Smart Contract Programmer recently posted a video explaining this: piped.video/rucZrL1nOO8 He discussed two scenarios: 1. Alice has DAI and Bob has ETH, Bob pays for gas fee. 2. Alice has DAI and Bob has nothing, but Carol has ETH. Alice pays DAI to Carol and let Carol pays for gas fee. The "meta transaction" scenario we discussed yesterday is similar to case 2. The gas-less token transfer shown in the video relies on "ERC20 Permit", which will be covered in the following tweet.
1
123
An interesting finding from @pashov private audit report: github.com/pashov/audits/blo… Tokens such as Synthetix's ProxyERC20 has 2 entry points (proxy and implementation). Both addresses refer to the same token. Attacker can use the alternative address to bypass this check:
2
243
I just took the @RareSkills_io Solidity Test and got 60%, I guess it is a pass?🤣Here is my test result: rareskills.testportal.net/ex… I believe there is no partial credit for multiple-choice question...Pretty solid test, good learning.
4
600
Here is a good code snippet that uses the "pull" pattern. Here a mapping `credits` records all users' balances. If a user wants to take their money out of the contract, it is his/her responsibility to call `withdrawCredits()`. A failed tx only impacts this user, not anyone else.
73
Below is a bad code snippet that uses the "push" pattern. In this case attacker can implement a fallback function that always reverts. He/she can bid to become `highestBidder`. When other people bid, `highestBidder.transfer(highestBid)` will be triggered and that tx will revert.
1
86
Replying to @dev_chinmayf
Yes, this is a good point to mention. This fact can be found in Solidity doc : docs.soliditylang.org/en/lat… Here is a screenshot of the relevant part:
1
43
What is the storage layout in inheritance pattern? For example, if you declare `contract MyContract is A, B`, state variables from A will be stored in the storage first, then those from B, then those in `MyContract`. Below is a code snippet where Ownable.sol is inherited:
1
307
And today I discovered the original version of Crew Love by Abel. This song without Drake is fucking amazing. piped.video/OaQwcXo7tx4
1
2
137
Thank you @_RastaMouse for the excellent course and exam! Look forward to taking CRTO II with you when it comes out.
2
2
15
And here is the recon part: piped.video/uKWu6yhnhbQ
My #nahamcon2022 Keynote recording is out! The Bug Hunter's Methodology: Application Analysis v1 piped.video/watch?v=HmDY7w8A… Learn my tips, tricks, & tools for web pentesting or bug bounty. Thanks Ben (@NahamSec ) & NahamCon! 🚨Retweet, follow, & like for more hacker content! 🚨
1
When dealing with ret2libc on 64-bit machines, be aware of the existence of stack alignment. Stack alignment aligns the stack in a 16-byte boundary (for optimization purposes). Adding a "ret" gadget before calling the system() function solves this problem. #ctf #pwn
2
1
1