Skip to content

Instantly share code, notes, and snippets.

@nervehammer
Created June 27, 2019 12:56
Show Gist options
  • Save nervehammer/ceb5ae79ed4e888e973bb944a0b55f11 to your computer and use it in GitHub Desktop.
Save nervehammer/ceb5ae79ed4e888e973bb944a0b55f11 to your computer and use it in GitHub Desktop.
pragma solidity ^0.5.5;
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";
import "openzeppelin-solidity/contracts/lifecycle/Pausable.sol";
import "tabookey-gasless/contracts/IRelayHub.sol";
import "tabookey-gasless/contracts/RelayRecipient.sol";
contract GaslessVanityURL is Ownable, Pausable, RelayRecipient {
mapping (string => address) private vanityAddress;
mapping (address => string ) private addressVanity;
event VanityReserved(address indexed to, string vanityUrl);
event VanityReleased(string indexed vanityUrl);
event RecipientPreCall();
event RecipientPostCall(uint usedGas, bytes32 preRetVal);
mapping (address => bool) public relaysWhitelist;
address public blacklisted;
constructor(IRelayHub rhub) public {
setRelayHub(rhub);
}
function setRelay(address relay, bool on) public {
relaysWhitelist[relay] = on;
}
function deposit() public payable {
getRelayHub().depositFor.value(msg.value)(address(this));
}
function withdraw() public onlyOwner {
uint balance = getRelayHub().balanceOf(address(this));
getRelayHub().withdraw(balance);
msg.sender.transfer(balance);
}
function setBlacklisted(address addr) public {
blacklisted = addr;
}
function acceptRelayedCall(
address relay,
address from,
bytes memory, /*encodedFunction*/
uint, /*gasPrice*/
uint, /*transactionFee*/
bytes memory /*approval*/
)
public view returns (uint)
{
if (relaysWhitelist[relay]) {
return 0;
}
if (from == blacklisted) {
return 3;
}
return 0;
}
function preRelayedCall(
address, /*relay*/
address, /*from*/
bytes memory, /*encodedFunction*/
uint /*transactionFee*/
)
public returns (bytes32)
{
emit RecipientPreCall();
}
function postRelayedCall(
address, /*relay*/
address, /*from*/
bytes memory, /*encodedFunction*/
bool, /*success*/
uint usedGas,
uint transactionFee,
bytes32 preRetVal
)
public
{
emit RecipientPostCall(usedGas * tx.gasprice * (transactionFee + 100)/100, preRetVal);
}
/**
* @dev Function to retrive wallet address from vanity url
*/
function retrieveWalletForVanity(string calldata vanityUrl) external view returns (address) {
return vanityAddress[vanityUrl];
}
/**
* @dev Function to retrive vanity url from address
*/
function retrieveVanityForWallet(address walletAddress) external view returns (string memory) {
return addressVanity[walletAddress];
}
/**
* @dev Function to reserve vanityURL
*/
function reserve(string memory vanityUrl) public whenNotPaused {
vanityUrl = _toLower(vanityUrl);
require(checkForValidity(vanityUrl));
require(vanityAddress[vanityUrl] == address(0));
require(bytes(addressVanity[msg.sender]).length == 0);
vanityAddress[vanityUrl] = msg.sender;
addressVanity[msg.sender] = vanityUrl;
emit VanityReserved(msg.sender, vanityUrl);
}
/**
* @dev Function to release a Vanity URL by Owner
*/
function releaseVanityUrl(string memory vanityUrl) public onlyOwner whenNotPaused {
address vanityHolder = vanityAddress[vanityUrl];
require(vanityHolder != address(0));
delete (addressVanity[vanityHolder]);
delete (vanityAddress[vanityUrl]);
emit VanityReleased(vanityUrl);
}
/**
* @dev Function to make lowercase
*/
function _toLower(string memory str) internal pure returns (string memory) {
bytes memory bStr = bytes(str);
bytes memory bLower = new bytes(bStr.length);
uint8 c;
for (uint i = 0; i < bStr.length; i++) {
c = uint8(bStr[i]);
if (c >= 65 && c <= 90) {
bLower[i] = bytes1(c + 32);
} else {
bLower[i] = bytes1(c);
}
}
return string(bLower);
}
/**
* @dev Function to verify vanityURL
*/
function _checkForValidity(string memory _vanityUrl) internal pure returns (bool) {
uint length = bytes(_vanityUrl).length;
uint8 c;
if (!(length >= 4 && length <= 200)) {
return false;
}
for (uint i =0; i < length; i++) {
c = uint8(bytes(_vanityUrl)[i]);
if ((c < 48 || c > 122 || (c > 57 && c < 65) || (c > 90 && c < 97)) && (c != 95)) {
return false;
}
}
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment