vado

url shortener for onchain people

Features

Fees

All fees are defined within the contracts, and are automatically applied when creating a link. Additionally, general access to the app and premium features require holding a certain amount of $VADO.

All fees and thresholds can be changed by the owner of the vado contract.

TypeAmount
Base fee0.001 Ξ per link creation
Discounted fee0.0001 Ξ per link creation if you hold amount of $VADO required for premium features
100 $VADO required in wallet to be able to create links
5000 $VADO required in wallet for premium features

Architecture

vado contracts

ContractDescription
Vado.solMain contract handling deployment and upgradeability. Inherits from all abstract contracts below:
VadoLinks.solAll link management logic and composition of other contract abstracts
VadoAccess.solAccess control mechanism for link creation
VadoFees.solFee management for link creation
VadoPremium.solPremium mechanism and modifier
VadoRandomizer.solHelpers for generating link codes
VadoToken.solERC20 utility token used as access token and premium features

All contracts are deployed on Base with proxy (UUPS upgradeable pattern).

vado resolver

As this has to happen in a browser, the actual resolver lives offchain as a single plain HTML file without any dependencies like it’s good ol’ 1999. After all, not more than 5 kB required to read from a smart contract. With no dependencies and without using any build tool, this makes the resolver easily deployable and reproducable everywhere, and for many years to come.

Within the resolver HTML file, the contract’s getUrl() method is called with standard Web Fetch API over a random public RPC, and a redirect is performed to the resolved URL. If this fails, it will try again with a different RPC until it succeeds or gives up after 5 tries.

Any passed pathname is considered the shortcode to be resolved. When no pathname is provided, it will redirect to app.vado.link.

Additionally, vadoAddress & chainId can be passed as optional query parameters mainly for testing purposes, where:

e.g. https://vado.link/5XE0i?vadoAddress=0x…&chainId=1337

The resolver content hash is stored in the vado contract as resolverContentHash for provenance and transparency. Itcan be used to verify that whatever runs under vado.link, vado.eth.link, vado.eth.limo is showing the intended content:

function resolverContentHash() external view returns (string memory);

Resolving from smart contracts

Contract exposes a getter method getUrl() which can be used to resolve a shortcode to a URL:

function getUrl(string memory code) external view returns (string memory);

vado app

Deployed under app.vado.eth which can be accessed by either:

vado token

The vado token (VADO) is a utility token for the vado service that enables access to premium features and fee discounts for creating links.

vado subgraph

in progress for public usage

The vado subgraph provides a GraphQL API for the vado service that allows you to query the data stored in the vado contracts.

E.g. to get all active links for a user:

{
  user(id: "0x...") {
    links {
      shortCode
      url
      createdAt
    }
  }
}

TODO: add more examples, figure out how to best allow public access to the subgraph

Domains

All domains can be used interchangeably, and will always resolve to the same service. This protects the service and therefore the short links you create from being taken down by any actor.

These domains only serve as an interface to the underlying contracts, the store of short codes to URLs can never be taken down by anyone. At the same time, everyone can create their own interface or resolver and point it to the underlying contracts.

This is used as the default domain for the service as it provides the most concise short links for now, and provides best compatibility for crypto and non-crypto users alike. But it is also the most centralized way of accessing the vado service.

Currently, the DNS on Cloudflare is configured to point to deployments of the resolver, app, and docs on Vercel. At the same time, the vado.link domain is an imported ENS name, so if you use a service or browser plugin that supports ENS, it will resolve to the underlying IPFS content hashes instead of the Vercel deployment.

vado.eth

The ENS name for the vado service, where the underlying account is the deployer and owner of the vado contracts.

Its content hash feature is then used to point to various parts of the vado service, like the resolver and app. The root ENS name is configured to point to the resolver content hash.

Subnames are then used for other components and if you use a service or browser plugin that supports ENS, it will resolve to the underlying IPFS content hashes:

in progress

This can be considered semi-decentralized, as the underlying service is controlled by a single entity.

Because vado.eth is configured with aforementioned mentioned subnames, these are mirrored here and can be used in every browser without special plugins or services:

TODO: figure out wildcard rewrites so e.g. vado.eth.link/SHORTCODE actually works

vado.eth.limo

in progress

This can be considered fully decentralized, as the underlying service is DAO-controlled.

Just like above, vado.eth is configured with subnames, so those are mirrored here too and can be used in every browser without special plugins or services:

TODO: figure out wildcard rewrites so e.g. vado.eth.limo/SHORTCODE actually works

Deployments

Base

ContractAddress
vado proxy0x45ae3dAeE940e81284807f727Ca7766ea37368c6
vado implementation0xEa8f74c24b18FD89D6635195b1ED8752C218CaAA
vado token0x97bb548b3ddb756771afb1903d3563f69465be8b

Base Sepolia (Testing)

ContractAddress
vado proxy0xbc32F0cCBFBEFEeaD6FEE13A86a10263e35cc838
vado implementation0x193591884C5f8527c86e331bA907cB1A7268C8e3
vado token0x29110781d0f22f7a645ff71a490d558f23fd98b4

built by alatus labs