pickle のハック
Pickle という Yearn っぽいコントラクトがハックされた。
https://picklefinance.medium.com/pickle-was-hacked-and-there-has-been-a-loss-of-funds-414b99969c29
https://peckshield.medium.com/pickle-incident-root-cause-analysis-5d73496ebc9f
https://github.com/banteg/evil-jar
audit は途中だったっぽい? https://docs.pickle.finance/faqs/security
https://github.com/pickle-finance/protocol/blob/master/audits/MixBytes_Audit_All_Strategies.pdf はあるが、strategy contracts だけを対象にしており、出来事に直接関係してそうな ControllerV4 とかはこのレポートの対象外の様子
Pickleの登場人物
https://github.com/pickle-finance/contracts ここに全てのコントラクトがリストされてたことに後から気づいた
https://miro.medium.com/max/2400/1*YATFV7728z5T0MxldbYneA.png
動きのサマリ
入金する(PickleJarにDAIを送金する)と、Controllerを経由してStrategyに送信されて、ファーミングに使われる(StrategyCompDaiならCompoundのmintを叩いてcDAIを得る)
出金する(PickleJarからDAIを取り出す)と、
PickleJar
ERC20 で pAsset に対応する
例えば pJar 0.88a の DAI https://etherscan.io/address/0x6949bb624e8e8a90f87cd2058139fcd77d2f3f87#code
https://docs.pickle.finance/picklejars/pjar-0.88
Controller の jars 変数(mapping)に DAI のアドレス(0x6b175474e89094c44da98b954eedeac495271d0f)を入力すると対応する Jar として 0x6949 ... が帰ってくるのであってるはず
https://etherscan.io/address/0x6847259b2b3a4c17e7c43c54409810af48ba5210#readContract の jars で試せる
deposit(uint256 _amount)
(事前に approve の必要あり)msg.sender から PickleJar へ DAI の送金を行い、pDai を発行する
withdraw(uint256 _shares)
引き出したい DAI を _shares として呼び出す(pDAIはburnされる) _shares / totalSupply() で割合を求め、balance() で取得する PickleJar が保有する DAI 数量に掛けて数量を算出する。harvest() の都度、明示的に PickleJar の全アカウントの balanceOf(address) を更新するようなことはしておらず、withdraw() のこのタイミングでファーミングして増えた分を計算して返している。Controller を経由して Strategy から DAI を引き出して、msg.sender へ送金する原資とする
earn()
持っている DAI の一部(available() によって計算される数量)を Controller に送金して Controller の earn(address, uint256) を実行
harvest(address reserve, uint256 amount)
Controller しか実行できない。Controller へ DAI(reserve で指定されるけど対応するトークンに限定していて、pDAI の jar では DAI に限定される)を amount だけ送金する
Controller
https://etherscan.io/address/0x6847259b2b3a4c17e7c43c54409810af48ba5210#code
earn(address _token, uint256 _amount)
_amount の数量の _token を対応する Strategy に送金して deposit() する
withdraw(address _token, uint256 _amount)
対応する Jar からしか呼び出せない。Strategy の withdraw(uint256) を呼び出すだけ
swapExactJarForJar
あるjarからあるjarに任意の額をswapする
Strategy
例えば StrategyCmpdDaiV2 https://etherscan.io/address/0xCd892a97951d46615484359355e3Ed88131f829D#code
deposit()
Strategy が持っている DAI を全部 compound に送金して cDAI を発行してもらう(実際には approve した上で compound の mint(amount) を叩く)
https://compound.finance/docs/ctokens#mint
withdraw(uint256 _amount)
Controller からしか呼び出せない。指定の amount から devfund と treasury の取り分を引いて Jar へ送金する
harvest()
compound の claimComp を呼び出して COMP を請求、もらった COMP を Uniswap で DAI に swap する。Controller に設定されている treasury と devfund の取り分を引いて、残りは Strategy に deposit() する
Converter
攻撃について
controller の