Skip to main content

· 6 min read
Rahul Saxena

Bullet-proof your PriceFeedManager contracts

Gm developers and fellow auditors!!

In almost any decentralised application in the domain of decentralised finance, one of the most critical components of the protocol is to fetch the prices of assets on-chain. This is mostly enabled by on-chain oracles.

Oracles are data feeds that bring data from off the blockchain (off-chain) data sources and puts it on the blockchain (on-chain) for smart contracts to use. This is necessary because smart contracts running on Ethereum cannot access information stored outside the blockchain network.

Unsurprisingly, protocols introduce a LOT OF bugs when implementing their contracts that interact with such oracles. This is mostly because it is quite hard to account for all the attack vectors due to the somewhat hybrid (off-chain and on-chain) nature of oracle interactions.

Hopefully, this article will help you to bid farewell to all the most common price feed contract bugs from your protocol. Read this thread and bid goodbye to all your price feed contract bugs.

This thread will be focused on the Chainlink oracles and how to deal with them, since they are one of the most popular choices. Other popular oracles are the Uniswap v3 Oracles, MakerDAO Oracle, etc.

Grab some popcorn, this is gonna be fun. Time for my top 10 tips:

via GIPHY

Let's begin our journey through these tips

Grab some Cola, cause these tips' delivery can get a bit spicy.

1. Backup Oracles are a must

As a degen, hedging risks must be a completely alien concept to you, but do not let that affect your dev life.

Consider implementing a back-up oracle in case your primary oracle goes down or does not support a specific token.

via GIPHY

· 16 min read
Rahul Saxena

Motivation

Note: You can also watch a phenomenal short video as an introduction to derivaties. This is recommended for people who already have a bit of understanding in this regard.

Derivative: A financial contract, whose value depends on it's underlying assets.

For example, an apple pie is a derivative of an apple as it is derived from the apple and the price of the apple pie is determined by the quality and quantity of the apples used to make it (among other things).

Similarly, the price of a financial contract that is derived from some underlying assets such as shares of stock is determined by the quality,quantity and current price of the underlying asset and is known as a derivative.

Derivative are of 4 types:

  • Options
  • Futures
  • Swaps
  • Forwards

· One min read
Rahul Saxena

Convert address to uint and back

This conversion exploits the fact that addresses take up 20 bytes and so does a uint160 (20 * 8).


// SPDX-License-Identifier: MIT

pragma solidity ^0.8.7;

// The theory behind this is that addresses take up 20 bytes in a word which is equivalent to (20*8) 160 bits and hence should be correctly casted to and from uint160.

contract AddressToUint {

address public targetAddress;
uint256 public targetUint;

function convertAddressToUint(address _targetAddress) external returns(uint256) {
targetAddress = _targetAddress;
targetUint = uint256(uint160(_targetAddress));
return targetUint;
}

function convertUintToAddress(uint256 _targetUint) external returns(address) {
targetUint = _targetUint;
targetAddress = address(uint160(_targetUint));
return targetAddress;
}

}

// 0xabD0127D996A468A79a0a8e88F4D419E40402e95
// 980877587572537262620952019491558306941665029781

· 2 min read
Rahul Saxena

Function Types

For official documentations follow this link.

So, in Solidity, you can pass functions themselves as parameters to other functions. These type of parameters are called function types.

These function types can be used to pass and return functions from function calls.

Example

1. Format of function types is the following:

function (<parameter types>) {internal | external} [pure | view | payable] [returns(<return types>)]

Note : Function types can only be internal or external. Also, the return types cannot be empty if the function in question does not return anything, in this case, completely omit the returns keyword.

· One min read
Rahul Saxena

Code snippets depicting modern Solidity

//SPDX-License-Identifier: MIT

pragma solidity 0.8.14;

contract ModernSolidityFeatures {
TestContract tcInstance = new TestContract();

function modernFunctionSelector() public view returns(bytes4) {
return tcInstance.square.selector;
}

function modernIsContract(address addr) public view returns(bool) {
return (addr.code.length > 0 ? true : false);
}

function conventionalIsContract(address addr) public view returns(bool) {
uint32 sizeOfAddressCodeSection;
assembly {
sizeOfAddressCodeSection := extcodesize(addr)
}
return (sizeOfAddressCodeSection > 0);
}

function conventionalFunctionSelector(string memory functionSignature) public pure returns(bytes4) {
return bytes4(keccak256(bytes(functionSignature)));
}
}

contract TestContract {
uint256 public number;

function square(uint256 a) public pure returns(uint256) {
return a*a;
}
}

· 5 min read
Rahul Saxena

Let us see today when and why do we use abi.encode vs abi.encodePacked.

What is a hash function?

A hash function has the following characterisitics:

  • A function that takes in arbitrary size input and outputs a data of fixed size
  • Properties:
    • Deterministic
      • hash(x) = h, every time without fail
    • quick to compute the hash
    • irreversible
      • given h, (really)hard to find x such that hash(x) = h
    • small change in input changes the output significantly
      • hard to find x, y such that hash(x) = hash(y)

· 17 min read
Rahul Saxena

Jet:

Yul is part of a greater family of EVM assembly languages

its basically EVM assembly wrapped into a language with some Ssyntactic sugar

What's great about that is that the only thing you need to write Yul is an understanding of the EVM. Looking at Yul contracts won't really get you to that point

So, let's get a bit of a deeper understanding of the EVM

What is an EVM

Consider Ethereum to be a global computer (with each node having its own permanent data store) and EVM is the processor. It basically handles smart contract deployment and execution. It is just a computation engine, and as such provides an abstraction of just computation and storage, similar to Java Virtual Machine(JVM).

The EVM executes its own bytecode intstruction set which higher level smart contract languages such as LLL, Serpent, Mutan or Solidity are compiled into. The EVM does not require to have any scheduling capability because Ethereum clients run through verified block transactions to determine which smart contract needs executing and in which order. This mechanism makes EVM a single-threaded mechanism.

  1. A Turing machine is a finite (there are a limited number of states, such as a coin toss will have only two states: HEADS or TAILS) state machine that has an unlimited supply of paper tape that it can write on and read back.

· 14 min read
Rahul Saxena

The International Testing Standard (TITS) for DeFi

Declaration Tweet.

Mission Statement

I believe that protocols need to be held to a higher standard of testing. Web3 protocols are decentralised, therefore there are no centralised authorities, and subsequently there is no regulatory pressure on the protocols to do quality checks on their protocols.

Is this an issue?
YES
Is this a big issue?
YES

Why?

Well, because, speaking strictly from an economic perspective, it makes much more sense for a protocol to use its time and developer resources on shipping a v2 of their protocol once the initial set of smart contracts are coded rather than spending it on testing their protocol. The protocols presently, try to, conviniently shift the burden of testing and quality assurance on the auditing firms and sometimes on insurance firms. However, Auditing + Insurance is still not enough to offer the level of peace of mind that people should have on software that handles their money.

Therefore, the development team, that is the most intimately familar with the code base, must make it a sacred duty of theirs (just like doctors take the Hippocratic Oath) to test their code to the best of knowledge and ability.