Approve詐欺まとめ改
前回approve詐欺についてのノートをペペって書いたら思ったより反響あったので改めてちゃんと確認と考察を交えたうえで改版を書きます。
(前回は徹夜明けで仕事行くまで暇だったから10分くらいで書き上げた駄作でした…..)
*注意事項
・本記事は初心者向けに書いているので途中説明事項を省いたりわかりやすいようにあえて改変している箇所ございます。ご了承ください。
・なっとう侍はいつも言っていますがエンジニアでも何でもないただの雰囲気初心者です。間違いは十分に考えられます。決して鵜呑みにせず自分でも調べましょう。又、間違いがあったらこっそりDMで教えて下さい。TLで全然違うじゃん!乙!!って言われたら泣いちゃいます。
Approve詐欺とは
approve詐欺とはトークンに生えているapproveメソッド(機能)を応用し、他人のウォレットから無断でお金をぶち抜く行為のことを指しています。
function _approve(address owner, address spender, uint256 amount) internal {
require(owner != address(0), "BEP20: approve from the zero address");
require(spender != address(0), "BEP20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
基本的にはほぼすべてのトークンにはこのメソッドが生えています。(作成者が作成する際任意で外すことはできるが基本はしない。)
なぜApproveメソッドが必要なのか
tokenのtransferには方法が2種類存在し、msg.sender(TXを発行した人)とトークンの残量を減らすアドレスが一致していないと使えないtransferメソッドと誰でも移動させることのできるtransferFromメソッドがあります。
【前提】そもそもトークンを送るという概念はトークンのコントラクトに対してアドレスAの保有枚数をx枚減らしてこのアドレスBの保有枚数をx枚増やすといったイメージです。
function _transfer(address sender, address recipient, uint256 amount) internal {
require(sender != address(0), "BEP20: transfer from the zero address");
require(recipient != address(0), "BEP20: transfer to the zero address");
_balances[sender] = _balances[sender].sub(amount, "BEP20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
↑上記の_transferでspender(トークンを送る人)の保有枚数をX枚減らしrecipent(受け取る人)のトークン枚数をX枚増やすといった処理をしています
・transfer
function transfer(address recipient, uint256 amount) external returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
こちらtransferメソッド(皆さんが通常使っているtransfer機能)のコードです。
transferのspenderがmsg.senderに強制的に書き換えられています(割愛してます)。その後_transferによって保有量を変更しています。
つまりこのtransferメソッドを使用するとTXを送った人の保有量が書き換えられるので他人が使うことで不都合は起きません。
https://bscscan.com/tx/0xfe98a2d895e7809d54b35fc56bcfb69812b6d903b40cb4d124a48cb71ae2e142
transferを使っているトランザクション例
・transferFrom
問題はこちら。
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "BEP20: transfer amount exceeds allowance"));
return true;
}
_transferで保有量を変更する際にmsg.senderではなくsenderで書いているので自由に他人の保有量を変更することができます。
これでは誰も安心してカソツーライフを送れませんよね?そのためにapproveがあります。
approveの内容については次章で説明しますのでここではtransferFromを使用する際は一旦_approveでそのTX(トランザクション)の内容が正しいかどうかがチェックされ正しければ_transferによってtokenの保有量が書き換えられると覚えといて下さい。
*そもそもtransferFromって必要なのかという疑問に対してですがこのメソッドがないと現状出回っているdexなどが機能しないので必要です。
https://bscscan.com/tx/0xcf91da653736c280eee89e1a620f90211fbc349737e44a611ead1129165eaf98
transferFrom使用例
Approveで何を行っているのか。(何をチェックしているのか)
approveにspender(許可するアドレス)、amount(許可する量)を記入しTXを発行すると_approveにその内容が書き込まれます。
function approve(address spender, uint256 amount) external returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
_approveの中を見ると
function _approve(address owner, address spender, uint256 amount) internal {
require(owner != address(0), "BEP20: approve from the zero address");
require(spender != address(0), "BEP20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
わかりずらいですが、簡単に説明するとこのトークンのコントラクトにmsg.sedner(approveのTXを発行した人)がアドレスAに対して何枚まではこのトークン許可するよという内容を保管します。
transferFromなどを使用した際に_approveで変更する内容を書き込みますが、その際に間違った内容であれば強制的にTXをfailさせられます。
例、owner(msg.sender)がapproveを使いアドレスAに対してトークンを1枚許可。
アドレスAがtransferFromで(owner, アドレスA, 3枚)という内容のTXを発行
→現状ownerからアドレスAに対して1枚しか許可されていないので内容が合わない。→failする
*(実際はsubで引いた数を書きこもうとするけどfailするって感じですが上記の認識で問題ないと思います。)
Approve詐欺の正体
正体もなにもトークンのowner(保有者)がそのアドレスに対してapproveしてたからぶっこ抜いといたよ☆ってだけです。
勝手にぶっこ抜くのは詐欺だとは思っているけどコントラクトの機能を正常に使ってるのでぶっこ抜かれても文句言えないよね、、、って内心思ってます。(むかつくけどな!!!)
よくある間違い
Q、パンケーキでapproveしているのですがrevork(approveの枚数を0にする)をした方がいいですか?
A、どっちでもいいと思う。したいならすれば?
【説明】
approveのrecipientに誰を設定したか考えましょう。パンケーキruterを設定しましたよね?なのでパンケーキはあなたから抜くことはできますが他の人やtokenのowner(作成者)は抜けません。
パンケ信用できない!(ハッキングされる可能性も含め)ならしてもいいと思います。
↑つまりよくわからないdexやアドレスに対してapproveするとぶっこ抜かれる可能性は十分あります。
Q、独自トークンをapproveしたのに他tokenを抜かれた!!
A、approveするtokenをすり替えれれた可能性大
【説明】
パンケだとtokenを選択した後そのtokenに対するapproveを求めてきますが、よくわからないサイトだとその限りではありません。
独自トークンのapproveを求められていると思ってたら実はTXをステーブルのapproveにすり替えられていた!みたいなケースは十分に考えられます。
【対策】
metamask等でTXを発行する前に内容を確認しましょう。
View full transaction detailsという項目を押すとTXの内容がみれたりamountする量を変更できます。
信用できないアドレスに対してapproveする際は見る癖をつけましょう。
Q、独自DEXに対してapproveしたらウォレットのtoken全部抜かれた!
A、基本的にはありえません。
【説明】
approveはtokenごとにするものでありtokenAに対してaprroveしたからと言って他のtokenBは抜けません。
【補足】
複数のapproveを求めるコントラクトをこっそり作り一回のTXで複数approveさせることってできないのかなと考えましたが。approveのownerはmsg.senderに強制的に書き換えられているので無理だと結論付けました。
![](https://assets.st-note.com/img/1639023228143-tSw0mbR1Pp.png?width=1200)
【可能性】
approveTXを複数飛ばして複数回approveさせることで複数個のtokenを抜くことは可能(approve押したけどもう一回metamaskポップアップしたから押しとこっていう初心者の油断を狙った方法)
【可能性B】
作られたtokenのapproveがmsg.sednerではない可能性
神記事↓
参考になったから金払いたい!!っていう変態さんはこちらをどうぞ
ここから先は
¥ 300
この記事が気に入ったらサポートをしてみませんか?