The assign statement is not a declaration. A declaration would be:
wire down;
If you never declare down such as this, it will be implicitly declared.
Section 6.10 of IEEE 1800-2012 states:
If an identifier appears on the left-hand side of a continuous assignment statement, and that identifier
has not been declared previously in the scope where the continuous assignment statement appears or
in any scope whose declarations can be directly referenced from the scope where the continuous
assignment statement appears (see 23.9), then an implicit scalar net of default net type shall be
assumed. See 10.3 for a discussion of continuous assignment statements.
and then:
See 22.8 for a discussion of control of the type for implicitly declared nets with the `default_nettype
compiler directive.
This (I believe) typically means a wire in Verilog and logic in SystemVerilog.
Now, as far as using the value before it is assigned, that's perfectly legal. As long as not declared after it is used or assigned.