はじめに
『DApps開発入門』という本や色々記事を書いているかるでねです。
今回は、現物資産NFTを分割所有している場合に、単一所有処理を実行できる仕組みを提案しているERC5505についてまとめていきます!
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
他にも様々なEIPについてまとめています。
概要
ERC5505では、ERC1155規格をベースにした資産担保型の分割所有プロジェクトに対して、「全体取得(トータルアクイジション)」を可能にするトコントラクトインターフェースの拡張を提案しています。
特に物理的な資産を扱うケースに焦点を当てており、最終的にその資産を丸ごと取得できる手段を提供することを目指しています。
動機
現実世界の資産をNFTとして分割所有できる仕組みが増えてきましたが、「全部買い取りたい」と思ったときに問題が発生します。
例えば、倉庫に保管された高級ワインの樽をNFTとして分割所有している場合、それを自宅に持ち帰りたい人が現れても、全てのNFTを集めるのが極めて困難です。
なぜなら、ブロックチェーンはオープンな環境なので、全取得を試みていることが誰の目にも明らかになります。
すると、売却側が価格を釣り上げたり、そもそもアクセスできない(秘密鍵を失った)アドレスが所有していたり、完全な取得が現実的に不可能になる場合があります。
このような課題を解決するには、全体取得という特別なアクションをサポートする仕組みが必要です。
ブロックチェーン上でも、特定条件を満たせば実現可能な方法を整備することで、より実用的な分割所有モデルが成立します。
仕様
//set the percentage required for any acquirer to trigger a forced sale
//set also the payment token to settle for the acquisition
function setForcedSaleRequirement(
uint128 requiredBP,
address erc20Token
) public onlyOwner
//set the unit price to acquire the remaining NFTs (100% - requiredBP)
//suggest to use a Time Weighted Average Price for a certain period before reaching the requiredBP
//emit ForcedSaleSet
function setForcedSaleTWAP(
uint256 amount
) public onlyOwner
//acquirer deposit remainingQTY*TWAP
//emit ForcedSaleFinished
//after this point, the acquirer is the new owner of the whole asset
function execForcedSale (
uint256 amount
) public external payable
//burn ALL NFTs and collect funds
//emit ForcedSaleClaimed
function claimForcedSale()
public
event ForcedSaleSet(
bool isSet
)
event ForceSaleClaimed(
uint256 qtyBurned,
uint256 amountClaimed,
address claimer
)
関数
setForcedSaleRequirement
function setForcedSaleRequirement(uint128 requiredBP, address erc20Token) public onlyOwner
強制的に資産を買い取れるようになる条件を設定する関数。
requiredBP
は「Basis Point(ベーシスポイント)」、つまりパーセンテージを示します(10000
= 100%)。
例えば、7000
を指定すれば「70%の所有が条件」という意味になります。
erc20Token
には、決済に使用するERC20トークンのアドレスを指定します。
これにより、ある人が定められた比率以上のNFTを所有していれば、残りを強制的に買い取る手続きに進めるようになります。
setForcedSaleTWAP
function setForcedSaleTWAP(uint256 amount) public onlyOwner
残りのNFT(=100%からrequiredBP
を引いた分)をいくらで買い取るか、その単価を設定する関数。
amount
は1つあたりの買い取り価格です。
この価格は、過去一定期間の平均価格(TWAP:Time Weighted Average Price)を使うことが推奨されています。
価格操作などを避けるため、短期的な価格変動ではなく、時間を加味した平均価格を使う設計です。
execForcedSale
function execForcedSale(uint256 amount) public external payable
実際に強制取得の支払いを行い、取得プロセスを確定させる関数。
事前に設定された条件(保有割合とTWAP)を満たしている必要があります。
amount
は、必要な残りNFTの数 × TWAPです。
成功すると ForcedSaleFinished
イベントが発行され、実質的に全体の所有者になります。
claimForcedSale
function claimForcedSale() public
NFTの元保有者が保有していたNFTをBurnし、代金を受け取る関数。
この処理により、NFTの存在自体が消えて所有権が新たな取得者のみになります。
処理が行われると ForcedSaleClaimed
イベントが発行されます。
イベント
ForcedSaleSet(bool isSet)
強制売却の設定が完了したときに発行されるイベント。
ForceSaleClaimed(uint256 qtyBurned, uint256 amountClaimed, address claimer)
NFTをBurnして代金を受け取ったときに発行されるイベント。
どれだけBurnされ、いくら支払われたかが記録されます。
補足
この一連の仕組みによって、分割所有された資産でも条件を満たせば最終的に「全部まとめて取得する」という選択肢が生まれます。
オープンなブロックチェーン上でも、こうした強制的かつ公平な取得プロセスを設けることで、資産の実利用や回収がしやすくなります。
補足
ETH対応とメタデータの更新
ERC5505では、支払いに使用されるトークンとしてネイティブのETHも考慮されています。
ただし、ETHそのままではERC20として扱えないため、Wrapped Ether(WETH)を使うことでERC20互換に対応できます。
これにより、他のERC20トークンと同じように処理できます。
また、forcedSale
が設定された後は、NFTのメタデータも更新されるべきです。
具体的には、残りのNFTの価値は、事前に設定されたTWAP価格が上限となることを明示する必要があります。
これは、買い取り価格が固定されている以上、それ以上の価格での売却ができない状態であることを明確にするためです。
セキュリティ
ガバナンス攻撃による価格操作のリスク
forcedSale
の実行は、通常はコントラクトのオーナーによって行われますが、その前提としてガバナンスによる提案と承認プロセスが必要です。
この仕組みには、1つ大きなリスクがあります。
それは、ガバナンスに対する攻撃により、特定のタイミングで価格(TWAP)を操作されてしまう可能性です。
このリスクを緩和するためには、単一のオーナーや少人数による決定ではなく、複数人による評議会(カウンシル)を設けて、透明性と正当性を担保することが望ましいです。
コントラクト内に留まる支払いトークンのリスク
forcedSale
が実行されると、買い手によって支払いトークン(ERC20)がコントラクトに預け入れられます。
これらのトークンは、元のNFT保有者がNFTをBurnして代金を受け取るまで、コントラクト内に保留された状態になります。
この期間中、資金はコントラクトにロックされるため、何らかのバグや脆弱性、あるいは不適切なアクセス制御があれば、資金が失われる可能性もあります。
そのため、この部分のセキュリティ監査やテストの徹底が強く求められます。
特に、資金の引き出し条件やBurnの仕組みが正しく機能するかのチェックは重要です。
引用
liszechung (@liszechung), "ERC-5505: EIP-1155 asset backed NFT extension [DRAFT]," Ethereum Improvement Proposals, no. 5505, August 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-5505.
最後に
今回は「現物資産NFTを分割所有している場合に、単一所有処理を実行できる仕組みを提案しているERC5505」についてまとめてきました!
いかがだったでしょうか?
質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!
他の媒体でも情報発信しているのでぜひ他も見ていってください!