A single-lot swap contract selling its whole DGX gold token balance for ether at a price its seller sets.
Historical Significance
A contract that handles a token which charges a fee on transfer, asking the token what the fee will be instead of assuming the amount sent is the amount received. Fee-on-transfer tokens went on breaking integrations for years, and DGX charged such a fee from the start.
Context
Digix issued DGX against physical gold, an early example of an asset backed token on Ethereum. In 2016 there was no automated market maker and no aggregator, so selling a holding meant a centralised exchange or a purpose-built contract like this one.
Key Facts
Description
A one-sided swap contract for DGX, the gold-backed token issued by Digix. Its constructor writes the DGX token address into storage along with a seller and a price in wei per token unit; only the seller can change the price afterwards.
There is no buy function. Sending ether to the contract triggers the sale: it refuses if it holds no DGX or if the payment is below the price of everything it holds, asks the token contract what transfer fee the transaction will incur, sends the buyer the whole balance minus that fee, and forwards the payment to the seller. Every trade clears the contract out.
Because the fee is queried from the token rather than assumed, the buyer receives what actually arrives rather than the nominal balance.
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Homestead Era
The first planned hard fork. Removed the canary contract, adjusted gas costs.
Bytecode Overview
Verified Source Available
This contract has verified source code on Etherscan.
Show source code (Solidity)
contract DgxToken {
function approve(address _spender,uint256 _value) returns(bool success);
function totalSupply() constant returns(uint256 );
function transferFrom(address _from,address _to,uint256 _value) returns(bool success);
function balanceOf(address _owner) constant returns(uint256 balance);
function transfer(address _to,uint256 _value) returns(bool success);
function allowance(address _owner,address _spender) constant returns(uint256 remaining);
function calculateTxFee(uint256 _value, address _user) public returns (uint256);
}
contract SwapContract {
address public seller;
address public dgxContract;
uint256 public weiPrice;
modifier ifSeller() {
if (seller != msg.sender) {
throw;
} else {
_
}
}
function SwapContract(address _seller, uint256 _weiPrice) {
dgxContract = 0x55b9a11c2e8351b4ffc7b11561148bfac9977855;
seller = _seller;
weiPrice = _weiPrice;
}
function () {
if (dgxBalance() == 0) throw;
if (msg.value < totalWeiPrice()) throw;
uint256 _txfee = DgxToken(dgxContract).calculateTxFee(dgxBalance(), address(this));
uint256 _sendamount = dgxBalance() - _txfee;
if (!DgxToken(dgxContract).transfer(msg.sender, _sendamount)) throw;
if (!seller.send(msg.value)) throw;
}
function setWeiPrice(uint256 _newweiprice) ifSeller returns (bool _success) {
weiPrice = _newweiprice;
_success = true;
return _success;
}
function totalWeiPrice() public constant returns (uint256 _totalweiprice) {
_totalweiprice = dgxBalance() * weiPrice;
return _totalweiprice;
}
function dgxBalance() public constant returns (uint256 _dgxbalance) {
_dgxbalance = DgxToken(dgxContract).balanceOf(address(this));
return _dgxbalance;
}
function withdraw() ifSeller returns (bool _success) {
uint256 _txfee = DgxToken(dgxContract).calculateTxFee(dgxBalance(), seller);
uint256 _sendamount = dgxBalance() - _txfee;
_success = DgxToken(dgxContract).transfer(seller, _sendamount);
return _success;
}
}
contract DgxSwap {
uint256 public totalCount;
mapping (address => address) public swapContracts;
mapping (uint256 => address) public sellers;
function DgxSwap() {
totalCount = 0;
}
function createSwap(uint256 _weiprice) public returns (bool _success) {
address _swapcontract = new SwapContract(msg.sender, _weiprice);
swapContracts[msg.sender] = _swapcontract;
sellers[totalCount] = msg.sender;
totalCount++;
_success = true;
return _success;
}
function getSwap(uint256 _id) public constant returns (address _seller, address _contract, uint256 _dgxbalance, uint256 _weiprice, uint256 _totalweiprice) {
_seller = sellers[_id];
if (_seller == 0x0000000000000000000000000000000000000000) {
_contract = 0x0000000000000000000000000000000000000000;
_dgxbalance = 0;
_weiprice = 0;
_totalweiprice = 0;
} else {
_contract = swapContracts[_seller];
_dgxbalance = SwapContract(_contract).dgxBalance();
_weiprice = SwapContract(_contract).weiPrice();
_totalweiprice = SwapContract(_contract).totalWeiPrice();
}
return (_seller, _contract, _dgxbalance, _weiprice, _totalweiprice);
}
}External Links
Related contracts
Digix
Same deployerThe earliest known attempt to deploy a smart contract on Ethereum mainnet (Aug 7 2015, thanateros.eth). Ran out of gas before code deposit; creation bytecode reconstructed exactly.
0x9a049f...a977a0August 7, 2015Greeter (draft)
Same deployerA failed Greeter deployment, the first of three attempts where the gas limit was too low to store the runtime code on-chain.
0xf9c2a9...4273c2August 7, 2015Greeter (draft)
Same deployerA failed Greeter deployment, the second of three attempts where the gas limit was too low to store the runtime code on-chain.
0x26b151...e63c3aAugust 7, 2015Greeter (draft)
Same deployerA failed Greeter deployment, the third of three attempts where the gas limit was too low to store the runtime code on-chain.
0x235287...1c90a7August 7, 2015Greeter
Same deployerThe Frontier Greeter - Ethereum's Hello World tutorial deployed by a 2000 ETH genesis wallet on Day 1, with mortal() exposed as a callable function.
0xcde4de...bf7864August 7, 2015Digix
Same deployerDGX 1.0, the Digix gold token ledger, deployed 14 January 2016. Gold backed ERC-20 with demurrage and custodian roles.
0x55b9a1...977855January 14, 2016