Contract Address Details

0xB18713Ac02Fc2090c0447e539524a5c76f327a3b

SWAPCAT Last Balance Update: Block #690
Created by 0xc965–c5cc12 at 0xd262–452aa7

Balance

0 AVAX

Fetching tokens...

Contract name:
SWAPCAT




Optimization enabled
true
Compiler version
v0.4.26+commit.4563c3fc




Optimization runs
200
EVM Version
default

Contract source code

/**
* Submitted for verification at blockscout.com on 2020-10-13 20:47:27.411983Z
*/
pragma solidity ^0.4.20;
// 😸 WWW.SWAP.CAT 😸
//
// a simple DEX for fixed price token offers directly from wallet to wallet
//
// users can set up erc20 tokens for sale for any other erc20
//
// funds stay in users wallets, dex contract gets a spending allowance
//
// payments go directly into the sellers wallet
//
// this DEX takes no fees
//
// mostly useful to provide stablecoin liquidity or sell tokens for a premium
//
// offers have to be adjusted by the user if prices change
//
// we need the erc20 interface to access the tokens details
interface IERC20 {
function balanceOf(address account) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);
// no return value on transfer and transferFrom to tolerate old erc20 tokens
// we work around that in the buy function by checking balance twice
function transferFrom(address sender, address recipient, uint256 amount) external;
function transfer(address to, uint256 amount) external;
function decimals() external view returns (uint256);
function symbol() external view returns (string);
function name() external view returns (string);
}
contract SWAPCAT {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// lets make mappings to store offer data
mapping (uint24 => uint256) internal price;
mapping (uint24 => address) internal offertoken;
mapping (uint24 => address) internal buyertoken;
mapping (uint24 => address) internal seller;
uint24 internal offercount;
// admin address, receives donations and can move stuck funds, nothing else
address internal admin = 0xc965E082B0082449047501032F0E9e7F3DC5Cc12;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// set up your erc20 offer. give token addresses and the price in baseunits
// to change a price simply call this again with the changed price + offerid
function makeoffer(address _offertoken, address _buyertoken, uint256 _price, uint24 _offerid) public returns (uint24) {
// if no offerid is given a new offer is made, if offerid is given only the offers price is changed if owner matches
if(_offerid==0)
{
_offerid=offercount;
offercount++;seller[_offerid]=msg.sender;
offertoken[_offerid]=_offertoken;
buyertoken[_offerid]=_buyertoken;
}
else
{
require(seller[_offerid]==msg.sender,"only original seller can change offer!");
}
price[_offerid]=_price;
// returns the offerid
return _offerid;
}
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// delete an offer
function deleteoffer(uint24 _offerid) public returns (string) {
require(seller[_offerid]==msg.sender,"only original seller can change offer!");
delete seller[_offerid];
delete offertoken[_offerid];
delete buyertoken[_offerid];
delete price[_offerid];
return "offer deleted";
}
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// return the total number of offers to loop through all offers
// its the web frontends job to keep track of offers
function getoffercount() public view returns (uint24){ return offercount-1;}
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// get a tokens name, symbol and decimals
function tokeninfo(address _tokenaddr) public view returns (uint256, string, string) {
IERC20 tokeni = IERC20(_tokenaddr);
return (tokeni.decimals(),tokeni.symbol(),tokeni.name());
}
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// get a single offers details
function showoffer(uint24 _offerid) public view returns (address, address, address, uint256, uint256) {
IERC20 offertokeni = IERC20(offertoken[_offerid]);
// get offertokens balance and allowance, whichever is lower is the available amount
uint256 availablebalance = offertokeni.balanceOf(seller[_offerid]);
uint256 availableallow = offertokeni.allowance(seller[_offerid],address(this));
if(availableallow<availablebalance){availablebalance = availableallow;}
return (offertoken[_offerid],buyertoken[_offerid],seller[_offerid],price[_offerid],availablebalance);
}
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// return the price in buyertokens for the specified amount of offertokens
function pricepreview(uint24 _offerid, uint256 _amount) public view returns (uint256) {
IERC20 offertokeni = IERC20(offertoken[_offerid]);
return _amount * price[_offerid] / (uint256(10) ** offertokeni.decimals())+1;
}
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// return the amount in offertokens for the specified amount of buyertokens, for debugging
//function pricepreviewreverse(uint24 _offerid, uint256 _amount) public view returns (uint256) {
// IERC20 offertokeni = IERC20(offertoken[_offerid]);
// return _amount * (uint256(10) ** offertokeni.decimals()) / price[_offerid];
// }
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// the actual exchange function
// the buyer must bring the price correctly to ensure no frontrunning / changed offer
// if the offer is changed in meantime, it will not execute
function buy(uint24 _offerid, uint256 _offertokenamount, uint256 _price) public returns (string) {
IERC20 offertokeninterface = IERC20(offertoken[_offerid]);
IERC20 buyertokeninterface = IERC20(buyertoken[_offerid]);
// given price is being checked with recorded data from mappings
require(price[_offerid] == _price,"offer price wrong");
// calculate the price of the order
uint256 buyertokenAmount = _offertokenamount * _price / (uint256(10) ** offertokeninterface.decimals())+1;
////// these 4 checks have been spared out since the final check suffices, this save ~50000 gas
//// // check if the buyers allowance and balance are right
//// require(buyertokeninterface.allowance(msg.sender, address(this)) >= buyertokenAmount, "Check the buyers token allowance");
//// require(buyertokeninterface.balanceOf(msg.sender) >= buyertokenAmount,"buyer not enough to pay");
//// // check if the sellers allowance and balance are right
//// require(offertokeninterface.allowance(seller[_offerid], address(this)) >= _offertokenamount, "Check the sellers token allowance");
//// require(offertokeninterface.balanceOf(seller[_offerid]) >= _offertokenamount,"seller not enough on stock");
// some old erc20 tokens give no return value so we must work around by getting their balance before and after the exchange
uint256 oldbuyerbalance = buyertokeninterface.balanceOf(msg.sender);
uint256 oldsellerbalance = offertokeninterface.balanceOf(seller[_offerid]);
// finally do the exchange
buyertokeninterface.transferFrom(msg.sender,seller[_offerid], buyertokenAmount);
offertokeninterface.transferFrom(seller[_offerid],msg.sender,_offertokenamount);
// now check if the balances changed on both accounts.
// we do not check for exact amounts since some tokens behave differently with fees, burnings, etc
// we assume if both balances are higher than before all is good
require(oldbuyerbalance > buyertokeninterface.balanceOf(msg.sender),"buyer error");
require(oldsellerbalance > offertokeninterface.balanceOf(seller[_offerid]),"seller error");
return "tokens exchanged. ENJOY!";
}
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// in case someone wrongfully directly sends erc20 to this contract address, the admin can move them out
function losttokens(address token) public {
IERC20 tokeninterface = IERC20(token);
tokeninterface.transfer(admin,tokeninterface.balanceOf(address(this)));
}
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// straight ether payments to this contract are considered donations. thank you!
function () public payable {admin.transfer(address(this).balance); }
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}

Contract ABI

[{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""},{"type":"string","name":""},{"type":"string","name":""}],"name":"tokeninfo","inputs":[{"type":"address","name":"_tokenaddr"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"losttokens","inputs":[{"type":"address","name":"token"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"string","name":""}],"name":"deleteoffer","inputs":[{"type":"uint24","name":"_offerid"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"uint24","name":""}],"name":"makeoffer","inputs":[{"type":"address","name":"_offertoken"},{"type":"address","name":"_buyertoken"},{"type":"uint256","name":"_price"},{"type":"uint24","name":"_offerid"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""},{"type":"address","name":""},{"type":"address","name":""},{"type":"uint256","name":""},{"type":"uint256","name":""}],"name":"showoffer","inputs":[{"type":"uint24","name":"_offerid"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"pricepreview","inputs":[{"type":"uint24","name":"_offerid"},{"type":"uint256","name":"_amount"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"string","name":""}],"name":"buy","inputs":[{"type":"uint24","name":"_offerid"},{"type":"uint256","name":"_offertokenamount"},{"type":"uint256","name":"_price"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint24","name":""}],"name":"getoffercount","inputs":[],"constant":true},{"type":"fallback","stateMutability":"payable","payable":true}]
            

Contract Byte Code

0x6080604052600436106100745763ffffffff60e060020a60003504166364473a1281146100ba578063657ce0ef146101c05780636a540b74146101e357806374759ae41461027557806394b1a131146102bf578063c2250f8b14610316578063e3ca70b014610348578063e3fb4aea1461036b575b600454604051600160a060020a0363010000009092049190911690303180156108fc02916000818181858888f193505050501580156100b7573d6000803e3d6000fd5b50005b3480156100c657600080fd5b506100db600160a060020a0360043516610380565b604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561012257818101518382015260200161010a565b50505050905090810190601f16801561014f5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561018257818101518382015260200161016a565b50505050905090810190601f1680156101af5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b3480156101cc57600080fd5b506101e1600160a060020a03600435166105ab565b005b3480156101ef57600080fd5b5061020062ffffff600435166106a7565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561023a578181015183820152602001610222565b50505050905090810190601f1680156102675780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561028157600080fd5b506102a7600160a060020a036004358116906024351660443562ffffff606435166107d2565b6040805162ffffff9092168252519081900360200190f35b3480156102cb57600080fd5b506102dc62ffffff60043516610922565b60408051600160a060020a039687168152948616602086015292909416838301526060830152608082019290925290519081900360a00190f35b34801561032257600080fd5b5061033662ffffff60043516602435610ad1565b60408051918252519081900360200190f35b34801561035457600080fd5b5061020062ffffff60043516602435604435610ba0565b34801561037757600080fd5b506102a76110f1565b6000606080600084905080600160a060020a031663313ce5676040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156103c857600080fd5b505af11580156103dc573d6000803e3d6000fd5b505050506040513d60208110156103f257600080fd5b5051604080517f95d89b410000000000000000000000000000000000000000000000000000000081529051600160a060020a038416916395d89b4191600480830192600092919082900301818387803b15801561044e57600080fd5b505af1158015610462573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561048b57600080fd5b8101908080516401000000008111156104a357600080fd5b820160208101848111156104b657600080fd5b81516401000000008111828201871017156104d057600080fd5b505092919050505082600160a060020a03166306fdde036040518163ffffffff1660e060020a028152600401600060405180830381600087803b15801561051657600080fd5b505af115801561052a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561055357600080fd5b81019080805164010000000081111561056b57600080fd5b8201602081018481111561057e57600080fd5b815164010000000081118282018710171561059857600080fd5b50959b949a509850929650505050505050565b600480546040805160e060020a6370a082310281523093810193909352518392600160a060020a038085169363a9059cbb9363010000009091049091169184916370a08231916024808201926020929091908290030181600087803b15801561061357600080fd5b505af1158015610627573d6000803e3d6000fd5b505050506040513d602081101561063d57600080fd5b50516040805160e060020a63ffffffff8616028152600160a060020a039093166004840152602483019190915251604480830192600092919082900301818387803b15801561068b57600080fd5b505af115801561069f573d6000803e3d6000fd5b505050505050565b62ffffff8116600090815260036020526040902054606090600160a060020a03163314610744576040805160e560020a62461bcd02815260206004820152602660248201527f6f6e6c79206f726967696e616c2073656c6c65722063616e206368616e67652060448201527f6f66666572210000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b5062ffffff166000908152600360209081526040808320805473ffffffffffffffffffffffffffffffffffffffff19908116909155600183528184208054821690556002835281842080549091169055828252808320929092558151808301909252600d82527f6f666665722064656c65746564000000000000000000000000000000000000009082015290565b600062ffffff82161515610869576004805462ffffff198116600162ffffff92831681810190931691909117909255600081815260036020908152604080832080543373ffffffffffffffffffffffffffffffffffffffff199182161790915594825280832080548616600160a060020a038c81169190911790915560029092529091208054909316908716179091559150610903565b62ffffff8216600090815260036020526040902054600160a060020a03163314610903576040805160e560020a62461bcd02815260206004820152602660248201527f6f6e6c79206f726967696e616c2073656c6c65722063616e206368616e67652060448201527f6f66666572210000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b5062ffffff811660009081526020819052604090209190915592915050565b62ffffff81166000908152600160209081526040808320546003835281842054825160e060020a6370a08231028152600160a060020a0391821660048201529251859485948594859416928492839285926370a082319260248084019391929182900301818787803b15801561099757600080fd5b505af11580156109ab573d6000803e3d6000fd5b505050506040513d60208110156109c157600080fd5b505162ffffff8a1660009081526003602090815260408083205481517fdd62ed3e000000000000000000000000000000000000000000000000000000008152600160a060020a039182166004820152306024820152915194965087169363dd62ed3e93604480840194938390030190829087803b158015610a4157600080fd5b505af1158015610a55573d6000803e3d6000fd5b505050506040513d6020811015610a6b57600080fd5b5051905081811015610a7b578091505b5062ffffff9790971660009081526001602090815260408083205460028352818420546003845282852054938590529190932054600160a060020a039384169b9184169a93909216985090965090945092505050565b62ffffff821660009081526001602090815260408083205481517f313ce5670000000000000000000000000000000000000000000000000000000081529151600160a060020a0390911692839263313ce567926004808301939282900301818887803b158015610b4057600080fd5b505af1158015610b54573d6000803e3d6000fd5b505050506040513d6020811015610b6a57600080fd5b505162ffffff8516600090815260208190526040902054600a9190910a908402811515610b9357fe5b0460010191505092915050565b62ffffff831660009081526001602090815260408083205460028352818420549284905290832054606093600160a060020a03928316939092169190819081908714610c36576040805160e560020a62461bcd02815260206004820152601160248201527f6f666665722070726963652077726f6e67000000000000000000000000000000604482015290519081900360640190fd5b84600160a060020a031663313ce5676040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610c7457600080fd5b505af1158015610c88573d6000803e3d6000fd5b505050506040513d6020811015610c9e57600080fd5b5051600a0a888802811515610caf57fe5b04600101925083600160a060020a03166370a08231336040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b158015610d1057600080fd5b505af1158015610d24573d6000803e3d6000fd5b505050506040513d6020811015610d3a57600080fd5b505162ffffff8a16600090815260036020908152604080832054815160e060020a6370a08231028152600160a060020a03918216600482015291519496508916936370a0823193602480840194938390030190829087803b158015610d9e57600080fd5b505af1158015610db2573d6000803e3d6000fd5b505050506040513d6020811015610dc857600080fd5b505162ffffff8a166000908152600360205260408082205481517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0391821660248201526044810188905291519394508716926323b872dd9260648084019391929182900301818387803b158015610e4e57600080fd5b505af1158015610e62573d6000803e3d6000fd5b5050505062ffffff89166000908152600360205260408082205481517f23b872dd000000000000000000000000000000000000000000000000000000008152600160a060020a039182166004820152336024820152604481018c90529151908816926323b872dd926064808201939182900301818387803b158015610ee657600080fd5b505af1158015610efa573d6000803e3d6000fd5b50506040805160e060020a6370a082310281523360048201529051600160a060020a03881693506370a08231925060248083019260209291908290030181600087803b158015610f4957600080fd5b505af1158015610f5d573d6000803e3d6000fd5b505050506040513d6020811015610f7357600080fd5b50518211610fcb576040805160e560020a62461bcd02815260206004820152600b60248201527f6275796572206572726f72000000000000000000000000000000000000000000604482015290519081900360640190fd5b62ffffff8916600090815260036020908152604080832054815160e060020a6370a08231028152600160a060020a0391821660048201529151908916936370a0823193602480850194919392918390030190829087803b15801561102e57600080fd5b505af1158015611042573d6000803e3d6000fd5b505050506040513d602081101561105857600080fd5b505181116110b0576040805160e560020a62461bcd02815260206004820152600c60248201527f73656c6c6572206572726f720000000000000000000000000000000000000000604482015290519081900360640190fd5b505060408051808201909152601881527f746f6b656e732065786368616e6765642e20454e4a4f592100000000000000006020820152979650505050505050565b60045462ffffff1660001901905600a165627a7a723058202ded0a597920941cbcfd5a0e7cfc098b605cc8bb98f1dcf9dd76aa4e73fe3c980029