Wednesday, November 29, 2023

181: Fixed Point Arithmetic

 Smart contracts require deterministic calculations. Many programming languages like Javascript employ floating point arithmetic, which is convenient to work with and simply gives us a "number" type for all numbers. However, the way computers store floating point numbers creates the possibility of rounding errors when doing calculations. Any kind of rounding error would be a catastrophe in a smart contract, so Solidity employs fixed point arithmetic. 

Smart contract developers must understand their level of precision and treat it as their atomic unit of calculation. Ethereum defines the Ether, Gwei, and Wei where one Ether is equal to 1e18 Wei. This precision becomes especially apparent when working with ERC20 tokens and Chainlink price feeds. You might be surprised  when you try to mint 1 token in your ERC20 contract and only receive a fraction of a coin in your wallet. Similarly, a Chainlink price feed will return a large value for a coins price in USD. In both cases this is because the level of precision in the values must be accounted for. Many price feeds return with 8 points of precision, which must be adjusted to achieve a constant level of precession across calculations. Defining precision levels as constants in your smart contract is a good practice. 

Monday, November 20, 2023

180: Checks, Effects, Interactions

 The unique security environment of Ethereum smart contracts and its component Solidity code demands a special set of best practices. One of these best practices is known as the CEI pattern, standing for Checks, Effects, and Interactions. This allows us to structure the order of our Solidity logic in a sensible and consistent way, and to minimize exploits and security risks. Firstly all checks and validations are performed. If any check fails, the function should revert at that point using one of Solidity's modifiers and errors. Next, effects are computed. This refers to updating any internal state in the contract and changing variables. This is done after the checks to insure that variables are only effected in valid ways. Lastly are the interactions. This is where funds are transferred and external contracts are called. By placing the interactions last it forces us to consider the potential impact on the contract's state before interacting with external entities, reducing the risk of reentrancy attacks and enhancing security. 

Tuesday, November 14, 2023

179: Reentrancy Attacks

 The nature of blockchain and the unique attributes of Solidity introduce a number of smart contract specific vulnerabilities. One of these exploits the block updating of Ethereum and is known as a reentrancy attack. This attack has been used in massive exploits stealing millions of dollars. The vulnerability stems from a smart contract calling an external contract which hosts malicious code. In this way, the reentrancy attack is similar to classic web vulnerabilities like cross site scripting. Once called, the malicious contract can now call the original contract again, "re-entering" it and even calling functions in unexpected ways. A simple contract that sends ether and then updates the balance can be exploited with this method, by repeatedly sending transfers of ether before the balance is updated. This can be mitigated by calculating all state changes before initiating any transfer of ether. These days, libraries like OpenZeppelin's ReentrancyGuard allow you to add the Nonreentrant modifier to your functions and protect against these exploits. 

Tuesday, November 7, 2023

178: Uniswap V3

 UniSwap is the leader of decentralized finance and their innovations are quickly forked to many different crypto ecosystem. Their V3 update is no exception. Uniswap V3 allows liquidity providers to choose a specific range to provide liquidity, allowing them more capital efficiency and greater fees at the expense of greater impermanent loss. A variety of fee tiers and volatility strategies allow liquidity providers to employ sophisticated strategies unthinkable in traditional finance, such as a fee earning limit order. The complex of these V3 positions are such they can no longer be represented as a fungible liquidity token for the pool, but must be represented as an NFT minted when the user enters the position. 

Monday, November 6, 2023

177: Chainlink Oracle

 Chainlink interfaces allow real time data to be injected to a smart contract. A common use for this is to obtain the live trading price of a token. By using Chainlink's Aggregator V3 Interface we can extract the price out of a tuple to use in our code. However, as with many things in Solidity, we need to be careful abput the number of decimals in the returned value and be sure to convert it as necessary. The Goerli test net value returns with 8 decimals, so must be converted into wei or USD as appropriate. 

Sunday, November 5, 2023

176: Collateral Contract

 Today I wrote a smart contract that can accept deposits and withdrawals of any ERC20 token. A user with a manager role calls a function with an ERC20 contract address, which creates a new vault for that token. Once created, tokens can be deposited and withdrawn from their respective vaults in the contract. Since we are working with ethereum, the movement of tokens must be approved in the ERC20 contract, and most of the transactions had to be verified with MetaMask and consumed gas on the Goerli test network. 

Saturday, November 4, 2023

175: Ownable and Access Control

 Open Zeppelin provides a suite of widely used tools for writing more secure smart contracts. For example, we can inherit from the Ownable contract to give our contract the ability to decide an owner upon construction. We can then restrict certain functions within the contract to only being callable by the owner. When more complex access control is required, Open Zeppelin libraries can be used to create a variety of roles. These roles can provide granular access to functions and allow the smart contract developer to control access with precision. 

190: Sablier

 The CodeHawks platform has an upcoming audit on the Sablier protocol, so I decided to read through the docs and familiarize myself with the...