Delivery vs Payment (DvP)
DvP is a common financial transaction exchange method where delivery of securities occurs at the same time that payment is made. It ensures that both parties fulfill their obligations simultaneously, reducing counterparty risk and the possibility of default.
Rayls supports two ERC token standards: ERC20 (a standard for creating fungible tokens) and ERC1155 (a standard for creating both fungible and non-fungible tokens).
Overview
The DvP contract allows anyone to create exchanges specifying some parameters (see methods below). Those exchanges are stored on the contract, referenced by their exchangeId, and they can be later executed by the counterparty (unless they are expired). A specific counterparty can be informed on the exchange creation, otherwise, the exchange will be open to any counterparty address to accept it.
Types
enum ExchangeStatus {
NOT_EXISTS,
INITIALIZED,
EXECUTED,
EXPIRED
}
enum AssetType {
ERC20,
ERC1155
}
struct Asset {
AssetType assetType;
address tokenAddress;
uint256 amount;
uint256 tokenId;
}
struct Exchange {
address creator;
Asset creatorAsset;
address creatorBeneficiary;
address counterparty;
Asset counterpartyAsset;
uint256 expirationDate;
ExchangeStatus status;
}
ExchangeStatusenumerates the possible states the exchange can find itself in.AssetTypeenumerates the token standards accepted by the contract.Assetdefines everything needed to know about an asset used in the exchange.assetTyperepresents the token standard;tokenAddressrepresents the token's contract address;amountrepresents the amount offered for the exchange;tokenIdis ERC1155-specific and defines the id for the token in the ERC1155 contract.
Exchangedefines everything that needs to be known about an exchange.creatorrepresents the exchange creator address;creatorAssetrepresents theAssetthecreatoris offering in the exchange;creatorBeneficiaryrepresents the address where the exchangecreatorwants thecounterpartyfunds to be deposited;counterpartyrepresents the exchange acceptor address;counterpartyAssetrepresents theAssetthecounterpartyis offering in the exchange;expirationDaterepresents an expiration date for the exchange to become invalid;statusrepresents the state the exchange finds itself in.
Observations
- The
creatoris the exchange initiator , thecounterpartyis the exchange acceptor.
Properties
uint256 public lastExchangeId;
mapping(uint256 => Exchange) public exchanges;
lastExchangeIdstores the most recently createdexchangeId;exchangesstores a mapping fromexchangeIds toexchanges;
Methods
createExchange(
Asset memory creatorAsset,
address creatorBeneficiary,
address counterparty,
Asset memory counterpartyAsset,
uint256 expirationDate
)
executeExchange(uint256 exchangeId)
- The
createExchangemethod should be called by thecreatorof the exchange.creatorAssetrepresents theAssetthecreatoris offering in the exchange;creatorBeneficiaryrepresents the address where the exchangecreatorwants thecounterpartyfunds to be deposited;counterpartyrepresents the exchange acceptor address;counterpartyAssetrepresents theAssetthecounterpartyis offering in the exchange;expirationDaterepresents an expiration date for the exchange to become invalid;
- The
executeExchangemethod should be called by thecounterpartyof the exchange.exchangeIdrepresents the id of the exchange thecounterpartywants to accept.
Observations
- If the
creatorBeneficiaryaddress isaddress(0), then the address used to receive thecounterpartyfunds will be thecreatoraddress. - If the
counterpartyaddress isaddress(0), then the exchange is open for anycounterpartyaddress to accept it. - The
exchangeIdstarts as 1 for the first exchange created, and increases by 1 for each following exchange created.
Events
event ExchangeInitialized(
uint256 indexed exchangeId,
Exchange exchange
);
event ExchangeExecuted(
uint256 indexed exchangeId,
address indexed executor
);
- When the
createExchangemethod is concluded successfully, theExchangeInitializedevent will be emitted. - When the
executeExchangemethod is concluded successfully, theExchangeExecutedevent will be emitted.
Errors
'DvPExchange.createExchange: INVALID_EXPIRATION_DATE'
'DvPExchange.createExchange: INVALID_EXCHANGE_ID'
'DvPExchange.createExchange: INSUFFICIENT_ALLOWANCE'
'DvPExchange.createExchange: INSUFFICIENT_BALANCE'
'DvPExchange.createExchange: NOT_APPROVED_FOR_ALL'
'DvPExchange.createExchange: INVALID_ASSET_TYPE'
'DvPExchange.executeExchange: EXCHANGE_NOT_INITIALIZED'
'DvPExchange.executeExchange: EXCHANGE_EXPIRED'
'DvPExchange.executeExchange: UNAUTHORIZED_SENDER'
'DvPExchange.executeExchange: INVALID_ASSET_TYPE for creator'
'DvPExchange.executeExchange: INVALID_ASSET_TYPE for counterparty'
'DvPExchange.executeExchange: TRANSFER_FAILED'
createExchangeDvPExchange.createExchange: INVALID_EXPIRATION_DATEoccurs when you try to create an exchange with an expiration date in the past (that is, trying to create an exchange that would be born already expired).DvPExchange.createExchange: INVALID_EXCHANGE_IDoccurs in the extremely exceptional case where theexchangeIds overflow theuint256DvPExchange.createExchange: INSUFFICIENT_ALLOWANCEoccurs when thecreatoruses an ERC20 token and hasn't allowed the DvP contract to use enough funds to supply the exchange demand they are trying to create.DvPExchange.createExchange: INSUFFICIENT_BALANCEoccurs when thecreatoruses any token and they don't have enough balance to supply the exchange demand they are trying to create.DvPExchange.createExchange: NOT_APPROVED_FOR_ALLoccurs when thecreatoruses an ERC1155 token and hasn't approved the DvP contract to use funds to supply the exchange demand they are trying to create.DvPExchange.createExchange: INVALID_ASSET_TYPEoccurs when theAssetTypeinformed in thecreatorAssetis invalid.
executeExchangeDvPExchange.executeExchange: EXCHANGE_NOT_INITIALIZEDwhen the exchangestatusis not initialized (and thus it's not ready to be accepted).DvPExchange.executeExchange: EXCHANGE_EXPIREDwhen the exchange is already expired.DvPExchange.executeExchange: UNAUTHORIZED_SENDERwhen the acceptor, who is trying to execute the exchange, is not the one determined by thecreator.DvPExchange.executeExchange: INVALID_ASSET_TYPE for creatorwhen theAssetTypeinformed in thecreatorAssetis invalid.DvPExchange.executeExchange: INVALID_ASSET_TYPE for counterpartywhen theAssetTypeinformed in thecounterpartyAssetis invalid.DvPExchange.executeExchange: TRANSFER_FAILEDwhen it is an ERC20 transfer and the transfer fails.
Updated 6 months ago
