Old attack vectors keep resurfacing with better branding.
AI agents become permissions.
RWAs become custody assumptions.
Restaking becomes correlated risk.
L2 growth becomes cross-chain complexity.
Building EVM Chronicle keeps reminding me how much of Ethereum is still hidden beneath the surface.
Code is visible.
Transactions are visible.
But state is where many of the real stories live.
there was a second, more critical, bug in the attacker's 7702 impl contract.
live for a full ~20 min before the attack, it allowed anyone to drain the vault's full 1,087 ETH balance
a single block later it was found, and the remaining 0.82 ETH was taken
https://t.co/XGM1kDxZPI
@TedPillows True. And that is why the other side has to innovate even harder.
It should embrace as many builders and researchers as possible, don't be like social layer that feel like another gate to pass through.
Last stretch for EVM Chronicle in the @Giveth Ethereum Security QF Round.
If you want to help push better Ethereum state research infrastructure forward, now is the time to support it.
https://t.co/E3uT5aALwE
Understanding the state of a smart contract is not straight forward. At least it wasn't until @evmchronicle_io gave us all a direct way to inspect it.
Learn more: https://t.co/CvdlaKipBL
Support: https://t.co/pELfbcQjjC
New exploit on Ethereum:
TrustedVolumes lost around $5.87M in WETH, USDT, WBTC, and USDC.
The exploit appears to involve a TrustedVolumes-controlled custom RFQ swap proxy:
0xeEeEEe53033F7227d488ae83a27Bc9A9D5051756
Victim contract / resolver:
0x9bA0CF1588E1DFA905eC948F7FE5104dD40EDa31
Exploiter:
0xC3EBDdEa4f69df717a8f5c89e7cF20C1c0389100
Trace exploit transaction:
https://t.co/pxUm6MWndY
See image below for the interesting things I found on this exploit.
Support @evmchronicle_io on @Giveth Ethereum Security QF Round.
If you believe Ethereum needs better ways to inspect real contract state, mappings, storage history, and execution flow, this is a good time to back the project and help push it forward.
https://t.co/9oF3KajdIM
Small details. Big security implications.
A view function can still revert.
PoC:
contract PriceReader {
uint256 public price;
function getPrice() external view returns (uint256) {
require(price > 0, "price not set");
return 1e18 / price;
}
}
This function is view.
But if price == 0, it still reverts.
Why?
view only means the function does not modify state.
It does not mean the function is guaranteed to succeed.
view means read-only.
It does not mean safe.
Wrapping up another audit on a Saturday.
Smart contracts + off-chain parts.
One thing is clear after all the hacks: the demand for off-chain audits is there.
And after ~30 such audits and more than 100 findings, I can confidently say @CDSecurity_io is one of the best choices.
Do you remember which tool was used to generate the seed for the compromised address?
For me, this looks more like a bulk private key compromise.
The possibilities in my mind now:
- maybe those addresses came from an old wallet with predictable or incremental key generation, and someone finally figured out the pattern
- maybe some Web3 app stored private keys without permission, then its database leaked
- or maybe, worst case, we are seeing an early hint of quantum-level key compromise on-chain 😭
Small details. Big security implications.
abi.encodePacked can create hash collisions when multiple dynamic values are packed together.
Example:
keccak256(abi.encodePacked(a, b));
If a and b are dynamic types like string or bytes, different inputs can produce the same packed bytes.
Example:
abi.encodePacked("ab", "c")
and:
abi.encodePacked("a", "bc")
both become:
"abc"
So their hash is the same.
The issue is not keccak256.
The issue is that packed encoding removes boundaries between dynamic values.
Use abi.encode(a, b) when boundaries matter.
Daily Solidity trivia:
msg.sender.code.length == 0 does not always mean the caller is a normal wallet.
Example:
require(msg.sender.code.length == 0, "no contracts");
This check can be bypassed during contract construction.
Why?
When a contract is inside its constructor, its runtime code has not been stored on-chain yet.
So if that contract calls another contract from its constructor:
msg.sender.code.length == 0
can still be true.
The caller is a contract, but at that moment it looks like an address with no code.
So this is not a reliable security boundary.
"No code right now" does not mean "not a contract."
EVM Chronicle just refactored code search from pattern-based matching to exact keyword search.
Before, search tried to interpret code patterns and match similar logic. Now it focuses on exact source keywords first, with filters for language, compiler version, contract name, import path, verified date, sort order, and duplicate source handling.
The result should be faster, simpler, and more predictable search behavior.
If you have ideas for another filter that would be useful, let me know.
Centralization bugs are always considered invalid during audits, as the parties are trusted.
Then, those same trusted parties are draining millions from protocols.
A failed low-level .call does not automatically stop the function.
The process can still continue.
Example:
function withdraw(address payable a, uint256 amount) external {
(bool ok, ) = https://t.co/cDk7ZwaFp3{value: amount}(""); // call fail
doSomethingElse(); // can still run even if ok == false
}