# Solidity/Vyper
## Solidity syntax
### 1) What are differences between "pure" and "view", "public" and "external"?
- `pure`--как `view`, но не может читать storage
- `view`--не может менять стейт
- `public`--доступна как снаружи, так и изнутри
- `external`-- доступна только снаружи, работает только с calldata
### 2) What is the "interface"?
Описание функций контракта, определяет ABI
### 3) How to use library? What kind of libraries you know?
```solidity
using Lib for type;
type a;
a.libFunc(b);
Lib.libFunc(a,b);
```
Контракт-библиотека
### 4) How to send ETH to address?
- транзакция с `value`
- `payable(address).transfer(value)` 2300 gas, error
- `payable(address).send(value)` 2300 gas, bool
- `payable(address).call{value: value}("")`, задаем gas, bool
- `SELFDESTRUCT`
## Contracts inheritance
### 1) Can we change mutability in overrided function?
Да, к более строгой(``nonpayable``->`view`->`pure`). `payable`--исключение.
### 2) How to call base function from overrided?
Через ключевое слово `super`:
```solidity
super.overridedFunc();
```
### 3) How to initialize base contract(call contructor)?
```solidity
contract Deriv is Base(5){
}
contract Deriv is Base{
constructor() Base(5){
}
}
```
## Factory pattern
### 1) What is factory pattern?
Контракт, который создаёт другие контракты. Полезно когда нужно много одинаковых контрактов (пары Uniswap).
### 2) How the address of new contract calculates?
- CREATE --`keccak256(rlp([sender_addr,sender_nonce]))[12:]`
- CREATE2 -- `keccak256(0xff+sender_addr+salt+keccak256(initialisation_code))[12:]`
### 3) Where is located bytecode of deploying contract?
Обычная фактори -- в байткоде контракта фактори
Clone Factory -- имплементация уже задеплоена, фактори деплоит минамальное прокси.
## Contracts deployment
### 1) How to deploy the contract?
Отправить транзакцию на адрес 0 с байткодом.
### 2) When we have several contract to deploy what issues we have?
Зависимость по адресам A от B и B от A, необходимо вычислять адрес второго контракта.
## Proxy patterns
### 1) Which proxy patterns do you know? How proxies do work?
- transparent
- beacon
- diamond
- clone
Прокси через delegatecall используют функции контракта-имплементации в контексте storage прокси.
### 2) What is "unstuctured" and "structured" storage?
В структурированом storage все переменные идут в слотах по порядку. В неструктурированом можем запихать подальше:
```
bytes32 private constant implementationPosition = bytes32(uint256(
keccak256(‘eip1967.proxy.implementation’)) – 1 ));
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
assembly {
r.slot := slot
}
}
```
### 3) What is trasnparent, diamond proxy?
В transparent proxy скрываются админские функции апгрейда и прочего. Если адрес вызывающего не совпадает с овнером, то вызов безусловно проксируется в имплементацию, а если совпадает, то смотратся сначала функции самого прокси.
Diamond proxy может использовать несколько контрактов имплементаций. Селектор функции соотносится с адресом соответствующей имплементации и вызов уходит туда. Может иметь индивидуальные области storage для каждой имплементации и совместные для нескольких из них.
### 4) What is storage collision? What is the storage "gap" in terms of proxies?
Коллизия это когда при delegatecall переменная попадает не на своё место. gap это массив в конце storage для сохранения постоянного размера storage наследуемых контрактов.
```solidity
contract A{
uint256 a;
uint256[99] __gap;
}
contract A{
uint256 a;
uint256 b;
uint256[98] __gap;
}
```
# EVM
## EVM design: bytecode, ABI
### 1) What is ABI? Explain how ABI is used in DApp to call some contract. What can you do, if you don't know ABI of some contract without source code on mainnet?
ABI -- описание параметров функций контракта, дает соответствие между селекторами функций и их названием и аргументами. Из ABI мы получаем селектор функции и её аргументы, что необходимо для создания коллдаты. Если нет ABI, но есть исходный код, то можно сгенерировать ABI. Если нет исходного кода, то можно вытащить селекторы из байткода и поискать в базе данных типа 4byte.
### 2) How you understand "stack based virtual machine". Describe work with stack for example pure function, accepting "a" and "b" and returning "a * b"
Стековая виртуальная машина использует стек для передачи параметров, а не регистры.
|OPCODE|STACK|DESC|
|-|-|-|
|PUSH1 0 | 0 | кладем на стек 0|
|CALLDATALOAD | a | кладем на стек 32 байта коллдаты со сдвигом 0 |
|PUSH1 32 | 0x20, a | кладем на стек 0x20 |
|CALLDATALOAD | b, a | кладем на стек 32 байта коллдаты со сдвигом 0x20 |
|MUL | a*b | перемножаем два верхних элемента стека и кладем на стек |
|PUSH1 0 | 0, a*b | кладем на стек 0 |
|MSTORE | | записываем второй элемент стека(a*b) в память по адресу в первом элементе(0) |
|PUSH1 32 | 0x20 | кладем на стек 0x20 |
|PUSH1 0 | 0, 0x20 | кладем на стек 0|
|RETURN | | возвращаем значение из памяти размера 0x20 по адресу 0|
## Call opcodes: CALL, STATICCALL, DELEGATECALL, etc
### 1) What is the difference between CALL and DELEGATECALL, what variant to use for "library" pattern
`DELEGATECALL` выполняется в контексте вызывающего контракта
### 2) What is the difference between CALL and STATICCALL, what keyword makes Solidity to generate STATICCALL insterad of CALL
- `STATICCALL`--view, pure
- не изменяет storage
### 3) What is better to use - CALL or STATICCALL if both works? Why?
`STATICCALL` предотвращает изменения storage
## Memory model: how storage slots work?
### 1) How much space takes storage of contract with one single storage variable "bool enabled" ?
32 байта-размер одного слота
### 2) How dynamic arrays are stored in storage. How to find address of i-th element of array in storage?
`keccak(slot)+i`
`slot`--номер слота, в который попадает массив, там хранится длина
### 3) How mapping is organized in storage, how to find address of slot, storing value under some key?
`keccak(concat(key, slot))`
`slot`--номер слота, в который попадает mapping, не хранит ничего
## Storage collisions
### 1) Describe a"real-life" close scenario, when storage slot collision can occur. And mitigation techniques
В прокси в 1 слоте хранится адрес овнера, в имплементации в первом слоте что-то другое. В итоге изменение переменной в имплементации приведет к изменению овнера прокси. Можно зарезервировать место в имплементации под переменные прокси, можно переменные прокси пихать подальше в storage.
### 2) I have a library contract with "uint256[5]" array in it. I replace it with library with "uint256[6]" array at the same place in code without other storage changes. Will it break the storage?
Если есть что-то после, то да:
```solidity
contract A{ старый
uint256[5] a;
}
contract A{ новый
uint256[6] a;
}
contract B is A{
uint256 b; при старом занимает 5 слот, при новом 6
}
```
Переменная `C` съехала с 5 слота на 6
## Proxy upgrade concerns
### 1) What is the main danger zones when we upgrade contract under proxy?
- Фронтран инициализации (решается upgradeToAndCall)
- Сломать storage
- Апгрейднуться на багованый контракт
### 2) If we have derived contract and want to add new field in the main one what we should do (contract under proxy)?
Уменьшить длину `__gap` на количество новых занимаемых слотов
## Opcodes gas cost
### 1) How the cost of MSTORE is calculated, what parameters are used in calculations? What is the cost difference between MSTORE 513 bytes and 514 bytes?
3+memory expansion
Memory expansion считается так:
сначала считаем новый размер памяти в слотах по 32 байта
```
memory_size_word = (memory_byte_size + 31) / 32
```
дальше считаем стоимость памяти
```
memory_cost = (memory_size_word ** 2) / 512 + (3 * memory_size_word)
```
итоговая стоимость расширения памяти равна разнице между старым значением стоимости памяти и новым
Разница в стоимости будет если мы записываем в конец памяти и объем уже занятьй памяти равен `32n+31`, тогда последний байт из 514 попадет на новый слот и займет на 1 слот больше. Разница в стоимости будет `memory_size_word(513)/256+1537/512`
### 2) How much cost the CALL opcode?
```
memory_expansion_cost + code_execution_cost + address_access_cost + positive_value_cost + value_to_empty_account_cost
```
- address_access_cost = 100 если вызываемый адрес "горячий" и 2600 если "холодный"
- positive_value_cost = 9000 если value не 0
- value_to_empty_account_cost = 25000 если вызываемый аккаунт пустой (нулевой нонс и баланс)
# Blockchain
## Consensus algorithms: PoS, PoW
### 1) What is the "network complexity" in PoW? Can it be a single number?
### 2) Who are the validators in PoS networks, if there no centralized assignment?
### 3) what's going on when 2+ miners propose different blocks at the same height?
## P2P networking limitations (race conditions, cap theorem)
### 1) Why p2p node first announces to other nodes hash of transaction(or block), not the whole transaction(or block)?
Для уменьшения нагрузки на сеть, сначала нода проверяет, нет ли у неё такого блока, потом запрашивает сам блок
### 2) How peer chooses, what next peer to ask for needed chunk from its list of known peers?
Расстояние в Kademlia DHT
### 3) There is tons of data in p2p network (torrents for example). What parts of this data is on YOUR currently working peer now?
## Hashing, encryption
### 1) What byte (00-FF) is the most often found in SHA-256 hashes?
Равномерное распределение
### 2) What MAXIMUM amount of 256-bit hashes I need to bruteforce, to find a hash, that is in range from THIS_HASH to (THIS_HASH + 2^16)
Максимум--бесконечно. Среднее--`2^256/2^16`
### 3) 160 bit of hash(public_key) is used as address in ETH. Is it safe? Why so?
160 бит хэш требует около 2^80 шагов для поиска коллизий, что дохрена
## Gas mechanics
### 1) How to calculate "cost" of execution of part of code, e.g. for cloud provider
### 2) What is cheaper - read from storage , or write to memory ?
В среднем--запись в память дешевле. Но, если мы читаем из storage прогретый слот, а записываем в чистую память с оффсетом 961, то стоимость чтения 100, а стоимость записи 101.
### 3) Why free transactions is insecure in public blockchains?
Бесплатное расходование вычислительных мощностей приводит к возможности DDoS
## Block finalization
### 1) What is "finality", can finalized block be discarded in behalf of other block? Why?
### 2) When user of PoS network can be sure, that his transaction is "mined"? In PoW network?
PoS--должно пройти несколько эпох, подтвердить блок должны более 2/3 валидаторов из случайно выбранного множества. В PoW сам выбираешь сколько блоков сверху тебе достаточно
## Uncle blocks, forks
### 1) Why there are not much uncle blocks, while thousands users are mining?
Сложность высокая, сделать два блока одновременно маловероятно
### 2) What is hardfork. When the applied hardfork "spilts" network to a two networks? Explain using example
Кардинальное изменение с потерей обратной совместимости. Если все согласны, то сплита не происходит, если общество раскалывается, то часть может продолжить майнить старую цепочку
## Merkle proofs
### 1) What is the size of merkle proof, proving presense of item in list, having 1025 elements. Tree is built using 256bit hashes
# Security concerns
## Overlow, underflow
### 1) What is binary representation of 127 in int8 and uint8 ?
uint8: 01111111
int8: 01111111
### 2) a > 0, b > 0, what is the value of "a" to perform guaranteed overflow of (a+b)
MAX_VALUE
Минимальное `b==1`, так что `a` должно быть максимальным.
### 3) a * b = c, what check can avoid overflow in c befor multiplication?
## DoS
### 1) Present example case, when REVERT can lead to DoS of contract
### 2) why checks like require(_to != address(0)) exist?
Вернуть 0 если что-то не так--типичная история для view функций.
Перевод токенов на 0 адрес равносильно их сжиганию, что в некоторых протоколах происходить не должно и является ошибкой.
## Re-entrancy
### 1) Send ETH to user and save flag, that ETH was sent, in contract, or save flag and send ETH? Why?
Сначала флаг, потом отправляем. Иначе в фоллбеке вызываем опять эту же функцию и она отправляет снова.
### 2) Can sending ETH from contract to user's address can be used for reentracy attack? How?
Нет, некуда в фолбек сваливаться
## SafeTransfer, SafeApprove
### 1) Why result of ERC20 operation should be checked? Present the scenario, when uncecked transfer() can lead to the problems
Есть 2 возможных варианта работы ERC20: revert, либо возврат false при ошибке.
Если мы не проверяем возврат, но у пользователя недостаточно средств или апрува, то трансфера не произойдет, однако мы об этом не узнаем.
### 2) tx1: approve(vasya, 100000), then tx2: approve(vasya, 10) - what can go wrong ?
Фронтраним второй апрув трансфером 100000 Васе.
## Missing auth checks
### 1) Explain how "onlyOwner" modifier works.
Проверяет совпадение `msg.sender==owner`
### 2) What functions are usually restricted in DeFi protocols and how they're usually defended (multisig, DAO voting)
Обычно это функции, которые изменяют параметры и логику работы протокола, апгрейды прокси, управление деньгами хранилища (оплата аудитов, гранты и тд). Мультисиг быстрее чем голосование, но менее децентрализован (хотя голосование напоминает мультисиг китов).
## Front-run, Sandwich, Back-run attacks
### 1) Scenario of "sandwich" attack.
- A: Обмен X на Y
- V: Обмен X на Y
- A: Обмен Y на X
В ходе первого обмена цена Y растет, в ходе второго растет еще больше и атакующий продает его по большей цене, чем покупал
### 2) Scenario of attack on "sandwich attack"
### 3) What is a "slippage check" in trading, how it's used in DeFi trades
Проверка выходной цены обмена
## Sending/approving ETH/ERC20
### 1) What are possible problems, where result of sending ETH is not checked?
ETH может быть не отправлен ХЗ
### 2) What are possible problems, where result of sending ERC20 is not checked?
### 2) Scenario of attack, when in Uniswap pair present ERC20 token, controlled by attacker
## Exotic tokens: deflationary, rebasing, fee on transfer, blacklist, hooks on action
### 1) Explain case for ERC677-compatible token (transferAndCall())
Чейнлиинк -- оплачиваем и получаем данные за одну транзакцию
### 2) How to decrease balances for ALL token holders proportionally by one transaction, that decreases totalSupply
ХЗ: держать два TS: сам токен и его TS1 выступает в роли доли во втором TS2
```solidity
uint256 newTs;
function balanceOf(address account) public view override returns (uint256) {
return _balances[account]*newTs/_totslSupply;
}
function totalSupply() public view override returns (uint256) {
return newTs;
}
```
### 3) What you will check thoroughly if you see new, unkonwn ERC20 token
## Malicious code running with delegatecall
### 1) Why delegatecall is so dangerous, when used in OUR contract?
Если есть возможность исполнения произвольного кода, то код в delegatecall может изменить storage нашего контракта или уничтожить наш контракт selfdestructом.
## Uninitialized proxy implementation
### 1) In what cases uninitialized implementation can be dangerous?
Если есть возможность вызвать selfdestruct в имплементации(delegatecall или прям в коде)
### 2) What can happen in the worse case?
DoS
## Untrusted arbitary external calls
### 1) Present an example, when user-supplied ERC20 token allows an attack to be performed
### 2) Simplest attack scenario, when some vault (contract, having ERC20 balances) allows to make CALL to externally controlled contract
Можно сделать вызов approve или transfer этим контрактом, что приведет к возможности забрать деньги у контракта.
## Simple price manipulations: shares based price oracles, dex price
### 1) Explain scenario of price manipulation attack, where some DeFi project uses Uniswap pair to get price of some token
# DeFi
## Regular AMMs: uniswap v2, pancake
### 1) What's the main idea of constant product reserve1 * reserve2 = const in Uniswap?
- Нельзя полностью убрать один из токенов
- Позволяет работать с любой ценой
- саморегулируется при помощи арбитражеров
### 2) Can I receive the price for swapping unknown amount of tokens in Uniswap?
Нет, чем больше меняем, тем менее выгодный курс
### 3) Lets take swap() function in Uniswap - where is needed amounts of swapping tokens is checked? Where is the price of swap?
```solidity
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data)
```
`amount0Out, amount1Out` -- количество токенов, которые мы получим.
## Multi-collateral lending: aave, compound
### 1) I put ETH as a collateral and borrow USDT. What mechanism will work if ETH price in USDT will dramatically drop down? Explain it
Залог обычно кладут с запасом к LTV. Допустим цена ETH 1000 USDT, мы хотим получить 100 USDT, LTV=150%.
Нам нужно заложить 100*1.5=150 USDT = 0.15 ETH залога минимум, пусть заложим с запасом, 0.2 ETH=200 USDT. обозначим ключевые точки цены ETH:
| цена 1 ETH в USDT | сумма залога в USDT | LTV |
|-|-|-|
| 1000 | 200 | 200% |
| 750 | 150 | 150% |
| 500 | 100 | 100% |
В промежутке от 1000 до 750 все нормально, залога хватает на минимальный TVL.
В промежутке от 750 до 500 включается механизм ликвидации -- любой может принести 100 USDT нашего долга и забрать 0.2 ETH (минус комиссии). Прибыль будет составлять до 50 USDT (минус комиссии).
При цене ниже 500--жопа, никто эти 0.2 ETH не выкупит, поскольку это убыточно: за 100 USDT мы получим меньше 100 USDT.
### 2) Describe main idea of flashloan. Describe process of profitable arbitrage trade between two DEXes using flashloan from "what contract calls what contract" view
Идея следующая: берем много денег без залога, зарабытываем ими деньги и возвращаем (в большинстве случаев с комиссией) в пределах одной транзакции. Не вернули--транзакция ревертится. TODO
## Yield farming, yield aggregators: yearn, harvers
### 1) What is a "vault"? Is yearn vault a token? Which tokens are on the balance of vault?
### 2) What is "farming"? Which operations brings profit to DeFi users?
## Advanced AMMs: curve(stable AMM), uniswap v3, balancer
### 1) Why can I want to provide liquidity only for some range in Uniswap V3?
Меньший объем средств обеспечивает тот-же эффект что и больший из-за концентрации их в диапазоне, в котором преимущественно идет торговля.
### 2) Explain main idea of Curve AMM? Why it uses central part of graphic close to linear?
Уменьшить проскальзывание для торговли токенов с одинаковой стоимостью (ETH-stETH, USDC-USDT-DAI).
### 3) What is the formula of constant product in Balancer ?
`x1^a1*x2^a2...=k`
## Isolated collateral lending: ruler, euler
### 1) Why Compound and AAve use only restricted lists of assets, that can be borrowed or supplied?
Пулы не изолированы, один токен с сомнительной жизнеспособностью может сильно попортить весь пул упав в цене.
## Liquid staking protocols
### 1) Explain the idea of LiDo
Застейканые деньги нельзя просто взять и продать, их надо либо вывести из работы, либо вообще ждать период лока.
Идея LiDo заключается не в прямой продаже этих токенов, а продаже доли владения этими токенами, в таком случае они приобретают возможность продаваться моментально и не затрагивая никак застейканые токены.
## Stablecoins: DAI, USDC, USDT
### 1) What's going on when USD price of DAI goes up and down.
Идет вверх(1.1 USD):
DAI минтятся все так-же как 1 доллар, за 101 USDC=101 USD мы получим 100 DAI=110 USD(CR=101%). Продаем их, увеличивая предложение на рынке, что приводит к снижению цены и получению профита.
Идет вниз(0.9 USD):
Покупаем 100 DAI=90 USD, сжигаем и получаем обратно свои 101 USDC=101 USD минус fee. Увеличивается спрос, уменьшается объем => DAI становится дороже.
### 2) Explain analogy of DAI vault and credit with collateral
ХЗ
## Bribes (ve tokens)
### 1) How "no value" governance tokens can be used to generate profit?
### 2) Explain main idea of Convex project
Собрать вместе две группы людей: тех, у кого есть LP, но мало CRV и тех, у кого много CRV и нет LP.
С помощью CRV бустятся награды для LP, прибыль делится между вкладчиками. Холдеры CRV получают хоть что-то, холдеры LP получают больше чем без CRV.
# Exploiting
## Mainnet forking in brownie/hardhat
### 1) What type of node used in brownie/hardhat to be able to fork mainnet ath the given block
### 2) How you think works emulation of mainnet from given block number in brownie/hardhat ?
## Writing tests in brownie/hardhat
### 1) What main features of brownie/hardhat are needed to fully repeat arbitrary transaction in mainnet on your machine
## Gas price calculation
### 1) How to measure gas spent by some function in contract in brownie/hardhat test ?
`brownie test --gas`
плагин hardhat--gas--reporter
## Flashloan usage
### 1) What is the flashloan?
### 2) When flashloan is dangerous?
### 3) Protocol takes price form Unswap V2, mints rewards based on it (for provided liquidity), burns rewards(returns liquidity). Describe the attack scenario
## Re-entrancy exploit
### 1) Tell "most formal" cause of rentrancy, when it's possible?
Баланс уменьшается после перевода ETH, во время перевода в fallbackе вызывается опять эта же функция, в которой баланс все еще не уменьшен и перевод идет снова.
### 2) Can transfer of ERC20 token trigger reentrancy? In what cases?
Может когда токен контроллируется атакующим.
### 3) Can transfer of ETH trigger reentrancy? In what cases?
Да, если хватает газа
## Calldata crafting
### 1) Present examples, when DeFi function accepts "bytes data" and how validation of this data can lead to attack
# Tools
## Etherscan, metamask
### 1) Find implementation of Compound in Rinkeby, supply Rinkeby ETH, borrow some assets and find self transaction in etherscan
## Brownie, hardhat, remix
### 1) Demonstract contract + test in hardhat/brownie, deploy this contract in the testnet in Remix and call some functions, using Metamask
## Infura, alchemy
### 1) Get a free node from Infura or alchemy, and send example transaction from Python using it in mainnet
## Decompilers
### 1) Decompile simple contract and found constants, try to find functions selectors
## Slither, mythril
### 1) Perform Slither analyze of some contract and present report
## Tx tracing: ethtx, tenderly
### 1) Decode one of hack transactions, describe key moments in calls log
## Contract source code verification
### 1) Deploy and verificate code of you own contract in Etherescan in test network (e.g. Rinkeby)
## Etherscan API
### 1) Receive all ERC-20 transfers into/from given DeFi protocol using Ethercan API