People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!
numeraire, a base value for all computations. DFX Finance maintains the assimilators which integrate with Curve to provide proportional liquidity to pools.deposit() for a Curve pool and receive LP tokens. During this process, a check occurs to see if the deposit amount is greater than zero. amount_ = (_amount.mulu(10**tokenDecimals) * 1e6) / _rate; token.safeTransferFrom(msg.sender, address(this), amount_);
67:B3:8B:98! Woah, that's awesome. It's super crazy to me that the data is sent in plaintext over NFC; I figured some type of encryption would be done by default.password of the field then attempt to edit the field like we tried before. Since the password is set, it works! We've got a NEW toothbrush as far as the device thinks.write_to_contract() to write error messages to the WASM address space.write_to_contract() calls allocate. This function allocates a large block of memory in the address space. Normally, this is a standard library from CosmWasm but can be overwritten by a developer. addr_validate() within our custom allocate() function, an infinite recursion call can be created.getenforce were removed as well.init_module was restricted but finit_module was not! They are the same exact call except one takes in a file and the other takes in a file descriptor. finit_module allows the author to get into the kernel and disable SELinux. They had to write a custom loader for this though, which is interesting. Overall, an interesting bypass for SELinux.try with 3 options for the catch. First, catch Error(...) catches a revert from the external contract with a particular reason string. Second, Panic catches a serious error like division by zero, an integer underflow or assert. catch (bytes memory) that will catch all other unhandled errors. So, what if we could cause a denial of service by triggering one of these outcomes? Or, if we could bypass the checks implemented in a specific catch but not another? Let's hack things!uint256, it will use the address or any other data that is provided. catch case. mint to create an asset or burn to remove it from existence. Then, using a proof, the other chain would know whether we owned an asset on it or not.increment should occur before the call to _safeMint. This worked as follows:
function mint(address to) public returns (uint256) {
uint256 newWarriorId = tokenIds.current();
_safeMint(to, newWarriorId);
tokenIds.increment();
return newWarriorId;
}
_safeMint() function has an external function call for onERC721Received inside of it. Since the CEI pattern is not followed and the contract is not using the standard library for preventing reentrancy, there is a major problem. _mint function again, it will fail because the token id wasn't incremented and already exists. However, there are other functions within the contract that could be interesting to us.crossChainTransfer() is used to send the assets from one chain to another. Calling this with a particular token ID will send the token from one chain to another.mint() with the attacker contract as the recipient. NOTE: The ID hasn't been incremented.crossChainTransfer to transfer the new id to chain B.mint() again from the recipient contract to mint the same NFT once again.claimAsset(), but it always goes to the proper user.claimAsset() was built to be gasless (free). This is because a new user will not have any assets on the L2, since they are currently transferring them over. Because of this, a malicious actor could send lots of invalid free claim tx's to cause a DoS. Well, not exactly.
isFreeTx := poolTx.GasPrice().Cmp(big.NewInt(0)) <= 0
// if the tx is free and it was reverted in the pre execution, reject the transaction
if isFreeTx && preExecutionResponse.isReverted {
return fmt.Errorf("free claim reverted")
} else { // otherwise
...