セキュリティトークンが盛り上がっていますが、今月「ERC-1400: Security Token Standard」としての提案がEthereum Improvement Proposal上で行われました。なお、この提案はFinalizeされていないため、ERCではなくEIP1400になります。
また、EIP1400は議論中のため、内容が変わることがあります。2018年9月30日時点で議論されている内容を大まかにまとめました。
- セキュリティトークンとは
- EIP1400で定義されているセキュリティトークンの要件
- 前提知識 - トランシェとは
- セキュリティトークンにメタデータが必要な理由-EIP1400のAbstractより
- function定義
- 今後の議論について
セキュリティトークンとは
こちらの記事でわかりやすく書かれています。
ユーティリティトークンはサービスの利用などで扱われますが、セキュリティトークンは有価証券と同じような使い方として、出る利益や所有を価値の裏付けとして扱います。
従来の有価証券の置き換えとして利用するために、証券法などの規制に準ずると見なされています。
セキュリティトークンの範囲がどのようなものなのか、配当を出したらセキュリティトークンなのか、裏付けが何であればセキュリティトークンであるのかなどは明確に定義されていません。
証券的な性質を持つものが現在セキュリティトークンとして呼ばれているように見えます。
EIP1400で定義されているセキュリティトークンの要件
MUST要件
MAY要件
- 署名されたデータをオンチェーンで検証するために、トランザクションに渡す
- SHOULD NOT
- 表明されている管轄区域にわたる資産クラスの範囲を制限してはならない
- SHOULD要件
- ERC20とERC777との互換性を持つ
前提知識 - トランシェとは
トランシェは金融用語であり、この言葉を前提にEIPではディスカッションが進められています。
社債や株式など複数のものを組み合わせて一つにした金融商品について、利回りやリスクで区分したものがトランシェというらしいです。
証券化において、リスクや条件の異なる証券を設定する場合、そのリスクや利回り等の条件の程度により区分することをトランチングといい、区分された各部分をトランシェといいます。 例えば社債の場合、各トランシェを優先社債、劣後社債の2区分とするトランチングや優先社債、中間の社債(メザニン社債)、劣後社債の3区分とするトランチング等があります。
トランシェは優先劣後構造を持ち、上位トランシェほどキャッシュフローを先に享受し、発生した損失は後で被る仕組みとなっています。この為、下位になるほど損失のリスクが高くなり、トランシェ間のリスクの差は利回りの差に反映されることになります。
図にするとおそらくこのような形ではないかと思います。この辺りは金融の人間ではないため、より詳しい方がいらっしゃったら定義を教えていただければ幸いです。
セキュリティトークンにメタデータが必要な理由-EIP1400のAbstractより
EIP1400ではメタデータが必要であると述べています。直感的には、有価証券についてその証券を表す説明や要素が必要とは感じますが、より具体的な例が挙げられています。
EIP1400のAbstractの引用を見ながら考えて行きます。
There are many types of securities which, although they represent the same underlying asset, need to have differentiating data tied to them. This additional metadata implicitly renders these securities non-fungible, but in practice this data is usually applied to a subset of the security rather than an individual security. The ability to partition a token holder's balance into tranches, each with separate metadata is addressed in the Partially-Fungible Token section. For example a token holder's balance may be split in two: Those tokens issued during the primary issuance, and those received through secondary trading.
多種類の証券があり、同じ資産を表しても関連づけられたデータを区別する必要がある。メタデータは証券をnon-fungible(代替不可能)なものとして扱う。メタデータは通常ここの証券ではなく証券の区分化された対象について適用される。
トークンホルダーの残高をトランシェに分割する機能はPartially-Fungible Tokenセクションで詳述するが、例えば、トークンホルダーの残高は、一次発行と二次取引で受け取ったものとで2つに分けられる。
ここでは、同じトークンでも、発行のステージによって区別したい場合にメタデータが必要であると述べています。
おそらく発行ステージによっては何らかの優先条項があったりすることが想定されているかと思います。
Security token contracts can reference this metadata in order to apply additional logic to determine whether or not a transfer is valid, and determine the metadata that should be associated with the tokens once transferred into the receiver's balance.
Transfers of securities can fail for a variety of reasons in contrast to utility tokens which generally only require the sender to have a sufficient balance. These conditions could be related to metadata of the securities being transferred (i.e. whether they are subject to a lock-up period), the identity of the sender and receiver of the securities (i.e. whether they have been through a KYC process, whether they are accredited or an affiliate of the issuer) or for reasons unrelated to the specific transfer but instead set at the token level (i.e. the token contract enforces a maximum number of investors or a cap on the percentage held by any single investor).
セキュリティトークンコントラクトは有価証券の譲渡が有効かどうかを判定するためのロジックを利用する際に、このメタデータを利用する。
証券の譲渡は単純な残高不足以外のいろいろな理由で失敗する。
・ロックアップの対象期間外
・有価証券引受人者の身元による理由(KYCプロセスを経ているかどうか、受け渡しなどを認定された者か、発行者の関係者かなど)
・最大の投資家数や単一の投資家が保有する割合の上限を設定でき、その上限を超えるなど
メタデータは、証券譲渡がシステム的にだけでなく、業務的、法的な意味合いでも問題なく譲渡できるかを定義するために利用されるとしています。コントラクトでこの処理を行うことで、トラストレスに譲渡の有効性確認を実行できると考えられます。
function定義
提案では、ERCとしての関数の定義も掲載されています。
- Partially-Fungible Tokenに関するfunction
- オペレーターに関係するfunction
- セキュリティトークンに関係するfunction
として3種類の分割で掲載しています。それぞれ以下に示します。
Partially-Fungible Tokenに関するfunction定義
トークンホルダーの残高をトランシェに分割する機能として、提案されています。
関数名 | 説明 | 定義 |
---|---|---|
getDefaultTranches | balanceOfを通じてトランシェ全体の総残高を照会するだけでなく、特定のトランシェの残高を決定する必要があるかもしれません。 | function getDefaultTranches(address _tokenHolder) external view returns (bytes32); |
setDefaultTranches | トークンホルダーは、バランスをいくつかのパーティション(トランシェ)に分割することができます。この機能は、特定のトークンホルダーアドレスに関連付けられているすべてのトランシェを返します。 | function setDefaultTranche(bytes32 _tranches) external; |
balanceOfByTranche | トランシェの残高を取得する | function balanceOfByTranche(bytes32 tranche, address tokenHolder) external view returns (uint256); |
sendByTranche | デフォルトのトランシェから他のトランシェへトークンを送る | function sendByTranche(bytes32 tranche, address to, uint256 amount, bytes data) external returns (bytes32); |
redeemByTranche | トークンホルダーがトークンを償還できるようにする。 | function redeemByTranche(bytes32 tranche, uint256 amount, bytes _data) external; |
tranchesOf | トークンホルダーは残高をいくつかのトランシェに分割できる | function tranchesOf(address _tokenHolder) external view returns (bytes32); |
オペレーターに関係するfunction定義
オペレーター、として資産を運用する人を設定するfunctionが提案されています。 オペレーターは以下のどれかから証券を動かす権限を付与されます。
- トークンホルダーとトランシェ(defaultOperators inherited from ERC777)
- あるトランシェの全てのトークンホルダー(defaultOperatorsByTranche)
- あるトークンホルダー全てのトランシェ(現在と未来)
- あるトークンホルダーのあるトランシェ(isOperatorForTranche)
関数名 | 説明 | 定義 |
---|---|---|
defaultOperatorsByTranche | あるトランシェのデフォルトのオペレータを返却する | function getDefaultTranches(address _tokenHolder) external view returns (bytes32); |
authorizeOperatorByTranche | あるトランシェのトークンについて、トークンホルダーはオペレーターを設定できる。 | function authorizeOperatorByTranche(bytes32 tranche, address operator) external; |
revokeOperatorByTranche | あるトランシェのトークンについて、トークンホルダーはオペレーターを解除できる。 | function revokeOperatorByTranche(bytes32 tranche, address operator) external; |
isOperatorForTranche | あるトランシェのホルダーのオペレーターであるかどうかを返す。上の4つのパターンいずれかに該当するならTrueを返す | function isOperatorForTranche(bytes32 tranche, address operator, address _tokenHolder) external view returns (bool); |
operatorSendByTranche | トークンホルダーの代わりにオペレーターがセキュリティトークンを送金できるようにする | function function operatorSendByTranche(bytes32 tranche, address from, address to, uint256 amount, bytes data, bytes operatorData) external returns (bytes32); or function operatorSendByTranches(bytes32 tranches, address froms, address tos, uint256 amounts, bytes data, bytes operatorData) external returns (bytes32[]); |
operatorRedeemByTranche | トークンホルダーの代わりにオペレーターがセキュリティトークンを償還できるようにする | function operatorRedeemByTranche(bytes32 tranche, address tokenHolder, uint256 amount, bytes operatorData) external; |
セキュリティトークンに関係するfunction定義
セキュリティトークン基本機能としてのfunctionが定義されています。
関数名 | 説明 | 定義 |
---|---|---|
getDocument | ドキュメントを取得する | function getDocument(bytes32 _name) external view returns (string, bytes32); |
setDocument | ドキュメントを設定する。これらの文書は、法的文書またはその他の参考資料とすることができる | function setDocument(bytes32 name, string uri, bytes32 _documentHash) external; |
canSend | 譲渡できるかの確認。不能であれば譲渡不可能の理由を返す | function canSend(address from, address to, bytes32 tranche, uint256 amount, bytes _data) external view returns (byte, bytes32, bytes32); |
issuable | 新規発行可能かを確認する | function issuable() external view returns (bool); |
issueByTranche | 新規発行。総供給量を増加させるときには必ずこの関数が呼ばれる | function issueByTranche(bytes32 tranche, address tokenHolder, uint256 amount, bytes data) external; |
今後の議論について
現在、EIP1400はissueを変えてEIP1410、EIP1411で議論が継続されております。WEBコールなどでも議論がされる予定です。
概ね好意的な反応が多いですが、トランシェについての実装などが複雑になってしまうなども指摘されており、標準化のためにシンプルなものにする方が良いという意見なども出ております。
影響の大きいトピックだと思いますので、今後も見守って行きたいと思います。